在我的Web应用程序中,我需要经常需要缓存一些数据 但变化较少。为了抓住它们,我创建了一个单独的静态类,它将这些字段保存为静态值。这些字段在第一次调用时初始化。请参阅下面的示例。
public static class gtu
{
private static string mostsearchpagedata = "";
public static string getmostsearchpagedata()
{
if (mostsearchpagedata == "")
{
using (WebClient client = new WebClient())
{
mostsearchpagedata = client.DownloadString("https://xxx.yxc");
}
}
return mostsearchpagedata;
}
}
这里webrequest只进行了一次,它运行正常,但是如果有大量没有,它们会被快速连续调用。用户和apppool已重新启动, webrequest多次进行,具体取决于大多数searchpagedata已初始化或未初始化。
如何确保webrequest只发生一次,所有其他请求等到第一次webrequest完成?
答案 0 :(得分:4)
您可以使用System.Lazy<T>
:
public static class gtu
{
private static readonly Lazy<string> mostsearchedpagedata =
new Lazy<string>(
() => {
using (WebClient client = new WebClient())
{
mostsearchpagedata =
client.DownloadString("https://xxx.yxc");
}
},
// See https://msdn.microsoft.com/library/system.threading.lazythreadsafetymode(v=vs.110).aspx for more info
// on the relevance of this.
// Hint: since fetching a web page is potentially
// expensive you really want to do it only once.
LazyThreadSafeMode.ExecutionAndPublication
);
// Optional: provide a "wrapper" to hide the fact that Lazy is used.
public static string MostSearchedPageData => mostsearchedpagedata.Value;
}
简而言之,当第一个线程在Lazy-instance上调用DownloadString
时,将调用lambda代码(本质上是.Value
)。其他线程将执行相同操作或等待第一个线程完成(有关详细信息,请参阅LazyThreadSafeMode
)。对Value-property的后续调用将获得已存储在Lazy-instance中的值。