2009-08-06 3 views
2

私はOLTPアプリケーションでスレッドの競合を起こしています。コード関与を検討しながら、私は以下のが見つかりました:あなたはスニペットで見ることができるようにロックブロック内でロックされたオブジェクトを変更します。

 lock (_pendingTransactions) 
     { 
      transaction.EndPointRequest.Request.Key = (string)MessageComparer.GenerateKey(transaction.EndPointRequest.Request); 

      if (!_pendingTransactions.ContainsKey(transaction.EndPointRequest.Request.Key)) 
      { 
       _pendingTransactions.Add(transaction.EndPointRequest.Request.Key, transaction); 

       return true; 
      } 
      else 
      { 
       return false; 
      } 
     } 

、「ロック」ブロック内で変更されたオブジェクトのロックがあります。そこに何か悪いですか?誰もがこのようなことをして問題を抱えていた?

答えて

3

専用ロックフィールド(クラスメンバ変数)を使用することをお勧めします。このようにロックを使用することはしばしばお勧めしません。専用のロック・フィールドがタイプObjectのものであり、通常はこのようになります:オブジェクト自体はいくつかのスレッド意識を持っている場合

private object _pendingTransactionLock = new object(); 

、このロック変数は_pendingTransactionの実装クラスに属している可能性があります。それ以外の場合は、フィールドの宣言クラスの_pendingTransactionに属している可能性があります。

あなたはどのタイプが_pendingTransactionであるかは言いません。これがSyncRootプロパティを提供する組み込みのコレクションクラスである場合、これはロックオンに適している可能性があります。

Jon Skeetの「何をロックするか」を参照してください。

0

一般的に言えば、オブジェクトを修正(または読み込み)するため、オブジェクトにロックをかけます。したがって、本質的に間違っていることはありません。

0

鍵の生成をロックブロックの外に行うことで、ロックの期間を短縮できます。これ以外にも、これはリスト/コレクション/配列を保護するロックのほぼ標準的な例です:ロックを取得し、存在するかどうかを確認し、存在しなければキーを追加してロックを解除します。

関連する問題