c# - 在线程中编辑文件

标签 c# xml

我目前正在开发一个 xml 服务,它是来自其他站点服务的 20 多个其他 xml 的总和。 所以起初它只是;

GetherDataAndCreateXML();

但显然获得 20 多个其他 xml,编辑和提供它需要时间,所以我决定将其缓存 10 分钟左右并添加一个带有 DateTime 属性的 final.xml 文件以检查它是否过时等。所以它变成了这样的东西;

var de = DateTime.Parse(x.Element("root").Attribute("DateTime").Value).AddSeconds(10.0d);

if (de >= DateTime.Now)
 return finalXML();
else
{
 RefreshFinalXml();
 return finalXML();
}

现在的问题是,10 分钟后的任何请求显然都需要太多时间,因为它正在等待我的太长 RefreshFinalXml() 函数。所以我这样做了;

if (ndt >= DateTime.Now)
 return finalXML();
else
{
 ThreadStart start = RefreshFinalXml;
 var thr = new Thread(start);
 thr.IsBackground = true;
 thr.Start();

 return finalXML();
}

这样,即使在第 11 分钟,我也只是返回旧的 final.xml,但同时我启动另一个线程在后台刷新当前 xml。因此,在第 13 分钟之后,用户可以毫不延迟地获得新数据。 但这仍然存在问题;它为 10 到 13 分钟之间的每个请求创建一个新线程(而第一个 RefreshFinalXml 仍在后台工作),显然我不能让这种情况发生,对吧?由于我不太了解锁定文件和检测文件是否被锁定,我添加了一个小属性,“更新”到我的最终 xml ;

if (ndt >= DateTime.Now)
 return finalXML();
else
{
 if (final.Element("root").Attribute("Updating").Value != "True")
  {
   final.Element("root").SetAttributeValue("Updating", "True");
   final.Save(Path);

   ThreadStart start = RefreshFinalXml; 
   //I change Updating Attribute back to False at the end of this function , right before saving Final Xml
   var thr = new Thread(start);
   thr.IsBackground = true;
   thr.Start();
  }
 return finalXML();
}

所以, 0-10 分钟 = 从缓存返回
10~13 分钟 = 从缓存返回,而只有一个线程正在刷新 final.xml 13 分钟以上 = 从缓存中返回

目前它有效并且看起来不错,但问题是;我对这类东西(xml 服务、线程、锁等)非常缺乏经验,所以我不确定它是否能在更艰难的情况下完美运行。例如,我的自定义锁定是否会在交通繁忙时产生问题,我是否应该切换到锁定文件等。

所以我正在寻找有关此过程的任何建议/更正,什么是“最佳实践”等。

提前致谢
完整代码:http://pastebin.com/UH94S8t6

同时为我的英语道歉,因为它不是我的母语,而且当我现在极度失眠/疲倦时,情况会变得更糟。

编辑:哦,我真的很抱歉,但不知何故我忘了提一件重要的事情;这一切都适用于 Asp.Net Mvc2。我认为如果它不是网络应用程序我可以做得更好一些,但我认为这会改变很多事情,对吗?

最佳答案

这里有几个选项。

方法#1

首先,您可以使用 .NET 的异步 API 来获取数据。假设您使用的是 HttpWebRequest你想看看BeginGetResponseEndGetResponse ,以及 BeginReadEndRead Stream 上的方法,您会得到响应。

例子

var request = WebRequest.Create("http://someurl.com");
request.BeginGetResponse(delegate (IAsyncResult ar)
{
    Stream responseStream = request.EndGetResponse(ar).GetResponseStream();
    // use async methods on the stream to process the data -- omitted for brevity
});

方法#2

另一种方法是使用线程池来完成您的工作,而不是创建和管理您自己的线程。这将有效地限制您正在运行的线程数量,并消除您在创建新线程时通常会受到的性能影响。

现在,您不想在等待时重复触发更新是对的

示例#2

您的代码可能如下所示:

// We use a dictionary here for efficiency
var Updating = new Dictionary()<TheXMLObjectType, object>;

...

if (de >= DateTime.Now)
{
    return finalXML();
}
else
{
    // Lock the updating dictionary to prevent other threads from
    // updating it before we're done.
    lock (Updating)
    {
        // If the xml is already in the updating dictionary, it's being
        // updated elsewhere, so we don't need to do anything.
        // On the other hand, if it's not already being updated we need
        // to queue RefreshFinalXml, and set the updating flag
        if (!Updating.ContainsKey(xml))
        {
            // Use the thread pool for the work, rather than managing our own
            ThreadPool.QueueUserWorkItem(delegate (Object o)
            {
                RefreshFinalXml();
                lock(Updating)
                {
                    Updating.Remove(xml);
                }
            });

            // Set the xml in the updating dictionary
            Updating[xml] = null;
        }
    }
    return finalXML();
}

希望这足以让您继续工作。

关于c# - 在线程中编辑文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4002818/

相关文章:

c# - 如何从 c# Unity 中的另一个脚本扩展类

C#,逻辑结构可以使用嵌套类吗?

c# - 如何在 C# 中构建 XML?

c# - 如何在前端外部触发 SignalR 命令

C# 在没有构建时引用的情况下在运行时调用静态方法?

c# - 将自定义数据/值传递到事件系统

java - JAXB - 对动态标签名称使用继承

java - java中解析xml字符串

java - 将没有 web.xml 的应用程序标记为可分发以用于 Tomcat session 复制

android - 使用上下滑动动画显示/隐藏 View