2016-11-29 7 views
1

定期的にコンテンツを更新したい辞書にアクセスするコードがあります。包含オブジェクトは複数のスレッド間で共有されます。ロックを使用してオンザフライでフィールドを更新する

ロックについてはよく分かりませんが、私の頭には2つのスレッドが当たっていると想像されます。最初のスレッドは次のスレッドの前に完了して実行されます。これはロックの本体が最初のスレッドが更新し、その後すべての未処理のスレッドが同じことをするので、共有の値を更新した場合にはかなり悪いことです。これがどのように機能するかを理解しています。

だから、そのビットのシナリオに依存するが、私の場合は私がロックする前に、それは私たちが更新し、ロック本体があることを確認して入るとしている辞書の参照コピーを作成しますので、この

if (DateTimeOffset.Now.Subtract(_lastResolve) > TimeSpan.FromMinutes(2)) 
      { 
       var copy = _configCache; 
       lock (_lock) 
       { 
        if (copy == _configCache) 
        { 
         var t = ResolveSettings(); 
         t.Wait(); 
         _configCache = t.Result; 
        } 
       } 
      } 

return _configCache; 

を思い付いcopy refはまだ同じ辞書をターゲットにしています。

私の質問は二重であり、ロックの動作を正しく理解していますか、第二に、この特定の問題のサウンドを処理するアプローチですか?

ありがとう

答えて

2

これはダブルチェックロックと呼ばれます。これについてはeを参照してください。 g。シングルトンパターンの場合はMSDNまたはSOです。

引用符付きコードと互換性のあるものを取得するには、ロック本体でもう一度_lastResolveをチェックしている可能性があります。しかし、datetime操作はかなりコストがかかるので、ポインタの割り当てとチェックは、必要なものを達成するためのより軽量な方法かもしれません。

_configCacheを揮発性として宣言して、コンパイラが望ましくない最適化を起こさないようにする必要があります。

これが役に立ちます。

+0

ありがとうございました。私は揮発性で読み上げます。 – Sam

関連する問題