如何防止静态方法中静态字段的多次初始化?

时间:2017-07-06 12:23:04

标签: c# asp.net

在我的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完成?

1 个答案:

答案 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中的值。