2016-06-12 61 views
0

使用System.Threading的Win Form應用程序。兩個線程threadA和threadB以相同的方法sumNumber啓動。 sumNumber更新變量合計。所以這兩個線程嘗試更新相同的變量。在WinForms中使用Monitor類時出錯。對象同步方法是從非同步代碼塊中調用的

使用監視器類來同步訪問總計變量。

獲得「類型的未處理的異常‘System.Threading.SynchronizationLockException’的一個運行時異常發生在WindowsFormsApplication2.exe

其他信息:對象同步方法是從代碼非同步塊調用。

如何正確使用Monitor類在此。

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();

爲成員變量,然後

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

可縮短

lock (TotalLock) 
{ 
    total = total + 10; 
} 
+0

因此Monitor對象只能用於引用類型而不能用於基元數據類型。 –

+0

方法簽名是'public static void Enter(object obj)',所以如果你傳入一個值類型,它會被裝箱並且所有的東西都會中斷 –

相關問題