2017-12-27 16 views
-2

ディスパッチャータイマーを使用してUIを更新するWPF C#アプリケーションがあります。ディスパッチャータイマーを使用したWPFでのスレッドロック

スレッドAでは、クラスDataProcessorで、変数「FinalMarkers」というカスタム構造体を更新しています。

static readonly Object mLock = new Object(); 
      static List<Storage.FiducialMarkers> finalMarkers; 
      public List<Storage.FiducialMarkers> FinalMarkers 
       { 
        get { return finalMarkers; } 
        set 
        { 
         lock (mLock) 
         { 
          finalMarkers = value; 
         } 
        } 
       } 

と、スレッドの実行内:私のUIフォームで

FinalMarkers = pullFiducialData();

、私はDataProcessorのインスタンスを渡しています、私は、以下のものを使用して、変数の更新をロックしてい

Formのコンストラクタ

変数を呼び出して、ディスパッチャタイマー持っている私は、その後
 protected DataProcessor Data = null; 

public FormView(DataProcessor _Data) 
     { 
         Data = _Data; 
      } 

:タイマーティック機能に

DispatcherTimer timer = new DispatcherTimer(); 
      timer.Interval = TimeSpan.FromMilliseconds(20); 
      timer.Tick += timer_Tick3d; 
      timer.Start(); 

を、私は値をつかむ:

 List<Storage.FiducialMarkers> tmpList = new List<Storage.FiducialMarkers>(); 

tmpList = Data._processingArgs.FinalMarkers; 

これはしばらく実行され、その後エラーなくクラッシュします。間違ったスレッドロックを処理していますか?

これは、別のスレッドのデータをディスパッチャタイマーに渡す正しい方法ですか?

ありがとうございます。

+0

私はあなたのロックに関連しているかどうかは疑問です。実装されているので、何も役に立ちません。どのような例外がスローされるのか把握し、スタックトレースとメッセージを含める必要があります。 – Evk

答えて

1

getsetでロックを解除する必要があります。

public List<Storage.FiducialMarkers> FinalMarkers 
    { 
     get { 
      lock (mLock) { 
       return finalMarkers; 
      } 
     } 
     set 
     { 
      lock (mLock) 
      { 
       finalMarkers = value; 
      } 
     } 
    } 

あなたがsetを呼び出しているときにロックがかかる場合は、同時に実行している2つのセッターから身を守る、しかし、あなたはgetを呼び出しているときに、ロックを取らないならば、セットが改ざんありそれが調整されていない読者によって読み取られている間の値である。これは、ライターがロックを保持しているかどうかにかかわらず発生します。ロックは、複数のスレッド間の合意です。 1つのスレッド(ライター)だけが契約にバインドされていれば、他のスレッド(リーダー)は不適切な瞬間に読み取りを終了し、何らかの矛盾または破損を引き起こす可能性があります。

ロックには、「このコードブロックを同時に実行しない」と表示されます。ロックブロック内にfinalMarkersにアクセスすることに関与するコードを入れることによって、すべてのスレッドに同意させる必要があります。

FYI:構造体自体に値の意味があるため、getを実行するときにコピーされます。

+0

ありがとう!これは長い間実行されますが、次に取得します: '未処理の例外:System.NullReferenceException:オブジェクト参照がオブジェクトのインスタンスに設定されていません。 FormView.timer_Tick3d(オブジェクト送信者、EventArgs e)の 'これはスレッドの安全性の問題である可能性がありますか、それとも他に何かを逃した可能性がありますか? – anti

+1

@antiこの変更を加えない場合とまったく同じ問題があります。同時に複数のスレッドから同じリストにアクセスしていますが、そのことはできません。 – Servy

+0

ありがとうございます。このような問題に取り組むために受け入れられる方法は何ですか?読み取り/書き込みロックはそれをしませんか? – anti

関連する問題