2011-05-28 12 views
13

値ExecutionAndPublicationを使用すると、デッドロックを引き起こす可能性があることLazyThreadSafetyMode状態のためのマニュアルを参照して原因でした例。私は、この値を使用するときにデッドロックを引き起こす可能性のある例をよりよく理解しようとしています。この値を使用するにあたっては、ChannelFactoryを初期化しています。私はChannelFactoryのコンストラクタが内部ロックを使用しているのを見ることができません(Reflectorでクラスをレビューする)ので、このシナリオはデッドロックの可能性に合わないと思いますが、デッドロックの原因となる可能性があるChannelFactoryを初期化するデッドロック。レイジー<T> ExecutionAndPublication - (なし初期化メソッドが存在しない場合はデフォルトコンストラクタ、)初期化メソッドが内部でロックを使用する場合、デッドロック

ので、要約し、私の質問は以下のとおりです。

  1. それはExecutionAndPublicationを使用してのChannelFactoryを初期化デッドロックが発生することは可能ですか?

  2. ExecutionAndPublicationを使用して他のオブジェクトを初期化するデッドロックを引き起こす可能性のある方法はありますか?

次のコードがあるとします。

class x 
{ 
    static Lazy<ChannelFactory<ISomeChannel>> lcf = 
     new Lazy<ChannelFactory<ISomeChannel>>(
     () => new ChannelFactory<ISomeChannel>("someEndPointConfig"), 
     LazyThreadSafetyMode.ExecutionAndPublication 
     ); 

    public static ISomeChannel Create() 
    { 
     return lcf.Value.CreateChannel(); 
    } 
} 

答えて

9
  1. 文書化されているようにです - それはすべてのロックを使用しない場合は、この使用法は、任意のデッドロックが発生することはできません。
  2. データベースから読み取って初期化する遅延値があるとしますが、いつでも1つのスレッドだけがDBにアクセスしていることを確認したいとします。 DBにアクセスする他のコードがあると、デッドロックが発生する可能性があります。次のコードを考えてみましょう:
void Main() 
{ 
    Task otherThread = Task.Factory.StartNew(() => UpdateDb(43)); 
    Thread.Sleep(100); 
    Console.WriteLine(lazyInt.Value); 
} 

static object l = new object(); 
Lazy<int> lazyInt = new Lazy<int>(Init, LazyThreadSafetyMode.ExecutionAndPublication); 

static int Init() 
{ 
    lock(l) 
    { 
     return ReadFromDb(); 
    } 
} 

void UpdateDb(int newValue) 
{ 
    lock(l) 
    { 
     // to make sure deadlock occurs every time 
     Thread.Sleep(1000); 

     if (newValue != lazyInt.Value) 
     { 
      // some code that requires the lock 
     } 
    } 
} 

Init()はDBから読み込むので、ロックを使用する必要があります。 UpdateDb()はDBに書き込むので、ロックも必要です。Lazyはこの場合も内部的にロックを使用するため、デッドロックが発生します。

この場合、ロックステートメント外のlazyInt.ValueへのアクセスをUpdateDb()に移動することによってデッドロックを修正するのは簡単ですが、それ以外の場合はそれほど簡単ではありません。

+1

偉大な答え@svick - 逆の順序で取得されたネストされたロックの古典的な例は、これは私が考えていた行に沿っています - シナリオを明らかにするための素晴らしい例、ありがとう! – dugas

関連する問題