2017-07-06 17 views
0

私のウェブアプリケーションでは、頻繁に必要なデータをキャッシュする必要がありますが、変更頻度は少なくなります。それらを保持するために、これらのフィールドを静的な値として保持するセパレート静的クラスを作成しました。これらのフィールドは、最初の呼び出しで初期化されます。以下のサンプルを参照してください。静的メソッドで静的フィールドの複数の初期化を防ぐ方法は?

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

ここでWebリクエストは1回だけ実行されますが、大丈夫ですが、大きな番号がある場合はすぐに呼び出されます。ユーザーとapppoolが再起動しました。 websequestはmostsearchpagedataが初期化されたかどうかに応じて複数回行われます。

webrequestが一度だけ実行され、その他のすべての要求が最初のWeb要求の完了まで待機することを確認するにはどうすればよいですか?

+0

あなたはシングルトンを探していて、それについて読むことができます。 https://stackoverflow.com/questions/2667024/singleton-pattern-for-c-sharp –

+2

これはスレッドセーフではないため、エラーが発生します。これにはシングルトンが必要です。参照 - http://csharpindepth.com/Articles/General/Singleton.aspx – Yogi

答えて

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; 

} 

を一言で言えば、ラムダコード(あなたDownloadString基本的に)最初のスレッドがレイジー・インスタンス上.Value呼び出したときに、呼び出されます。他のスレッドは同じことをするか、最初のスレッドが終了するのを待ちます(詳細はLazyThreadSafeModeを参照してください)。その後のValue-propertyの呼び出しは、Lazy-instanceにすでに格納されている値を取得します。

関連する問題