我目前正在开发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应用程序,我想我可以做得更好但我认为这会改变很多事情吗?
答案 0 :(得分:1)
你在这里有几个选择。
首先,您可以使用.NET的异步API来获取数据。假设您正在使用HttpWebRequest
,那么您需要查看BeginGetResponse
和EndGetResponse
以及BeginRead
和EndRead
方法{ {1}}你得到了回复。
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
});
希望这对你来说足够了。
答案 1 :(得分:0)
我会采用不同的方法,假设以下
我推荐1和2,但3更可选。