在线程中编辑文件

时间:2010-10-23 06:28:23

标签: 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分钟之后的任何请求显然需要花费太多时间,因为它正在等待我的looong 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上进行。如果它不是一个Web应用程序,我想我可以做得更好但我认为这会改变很多事情吗?

2 个答案:

答案 0 :(得分:1)

你在这里有几个选择。

方法#1

首先,您可以使用.NET的异步API来获取数据。假设您正在使用HttpWebRequest,那么您需要查看BeginGetResponseEndGetResponse以及BeginReadEndRead方法{ {1}}你得到了回复。

实施例

Stream

方法#2

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

现在,你在等待

时不想重复发布更新是正确的

示例#2

您的代码可能如下所示:

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
});

希望这对你来说足够了。

答案 1 :(得分:0)

我会采用不同的方法,假设以下

  • 您的服务一直在运行
  • 即使您目前没有对您的服务有任何要求,您也可以获得/被允许获取XML文件。
  • 您获取的XML文件与您的所有请求相同。 (即所有响应所需的XML文件总数为20个文件)
  • 生成的XML文件不能太大,无法始终保留在内存中

1

首先,我不会将生成的XML存储在磁盘上的文件中,而是存储在静态变量中。

2

其次,我会在10分钟内创建一个计时器,即使您没有呼叫您的服务,也会更新缓存。这样,即使您的服务暂时没有被调用,您也总是准备好并缓存最近的数据。它还消除了考虑您是否已经“正在进行”刷新的需要。

3

第三,我会考虑使用线程/异步调用来并行获取所有20个XML。这仅在您希望减少刷新时间时才有用。如果能够改善您的服务,它可以让您将刷新间隔从10分钟缩短到1-2分钟。

我推荐1和2,但3更可选。