2016-06-12 37 views
0

System.Threadingを使用するWinフォームアプリケーション。 2つのスレッドthreadAとthreadBは、同じメソッドsumNumberで開始されます。 sumNumberは変数を合計に更新します。これらの2つのスレッドは同じ変数を更新しようとします。WinFormsでMonitorクラスを使用中にエラーが発生しました。非同期コードブロックからオブジェクト同期メソッドが呼び出されました

変数へのアクセスをモニタークラスを使用してに同期させます。

『System.Threading.SynchronizationLockExceptionは』 WindowsFormsApplication2.exe

で発生しました追加情報"のランタイム例外にタイプの未処理の例外を取得:オブジェクトの同期方法は、コードの非同期のブロックから呼ばれていました。私が正しく、この中にモニターのクラスを使用するにはどうすればよい

int total; 

private void button3_Click(object sender, EventArgs e) 
     { 
      listBox1.Items.Clear(); 
      total = 0; 

      Thread threadA; 
      Thread threadB; 

      threadA = new Thread(sumNumber); 
      threadA.Start(); 
      threadB = new Thread(sumNumber); 
      threadB.Start(); 

      threadA.Join(); 
      threadB.Join(); 

      listBox1.Items.Add("Total is: " + total); 
     } 

     public void sumNumber() 
     { 
      long numRepeats = 100000; 

      for (int i = 0; i < numRepeats; i++) 
      { 
       Monitor.Enter(total); 
       total = total + 10; 
       Monitor.Exit(total); 
      } 

     } 

答えて

1

Monitor.EnterとMonitor.Exitに渡したオブジェクトは同じでなければなりません。合計の値が変化するので、Monitor.Exitは終了しようとするが、同じ目的を有する任意の対応Monitor.Enterがない、従ってあなたに

private readonly object TotalLock = new object();

を有していなければならない例外

を投げますメンバー変数は、

lock (TotalLock) 
{ 
    total = total + 10; 
} 
短縮することができる

Monitor.Enter(TotalLock); 
total = total + 10; 
Monitor.Exit(TotalLock); 

+0

したがって、Monitorオブジェクトは参照型でのみ使用でき、プリミティブ型では使用できません。 –

+0

メソッドのシグネチャは 'public static void Enter(object obj)'です。値の型を渡すとボックス化され、すべてが壊れます –

関連する問題