2010-07-30 96 views
3

我們正在利用我們的vb.net應用程序的一部分並行擴展檢索從dictonary的數據表(字符串,數據表)。在檢索表的方法中,我們使用Monitor.TryEnter。有時,我們收到錯誤「對象同步方法是從一個未同步的代碼塊調用的。」下面是我們的方法是什麼樣子:Monitor.TryEnter諮詢

 Try 
      if Monitor.TryEnter(_ProductCollection, 200) = true then 
       _ProductCollection.TryGetValue(name, ReturnValue) 
      end if 
     Finally 
      Monitor.Exit(_ProductCollection) 
     End Try 

我應該嘗試實現一個循環,以確保我們獲得鎖,試圖退出之前?我想這個錯誤正在拋出,因爲我試圖做monitor.exit,即使monitor.tryenter爲false。

+0

字典支持從多個線程讀取的時間,所以也許你甚至不需要顯示器電話(如果你有可能在同一時間寫,那麼你確實需要它,你需要保護用相同的同步調用寫入)。 – zneak 2010-07-30 05:14:56

+0

是的,我們正在同時閱讀和寫作。上面的代碼與寫入功能非常相似。 – 2010-07-30 06:20:24

回答

3

錯誤正在從Monitor.Exit調用拋出。正在發生的事情是,TryEnter timesout偶爾和未獲取鎖,但Monitor.Exit總是叫,因爲它是finally塊。那就是問題所在。這裏是你如何解決它。

Dim acquired As Boolean = False 
Try 
    acquired = Monitor.TryEnter(_ProductionCollection, 200) 
    If acquired Then 
    ' Do your stuff here. 
    End If 
Finally 
    If acquired Then 
    Monitor.Exit(_ProductionCollection) 
    End If 
End Try 
+0

如果您在'If Monitor.TryEnter(...)'部分中的'Try' /'Finally'內部,像[MSDN文檔](http://msdn.microsoft.com)那樣可以保存'Boolean' /en-ca/library/4tssbxcw.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2)爲'Monitor.TryEnter'顯示。 – 2014-06-11 16:57:02

+0

@JeffBridgman:的確如此。然而,我特別選擇了這裏的結構,因爲通過在'Try'關鍵字之前簡單調用'RuntimeHelpers.PrepareConstrainedRegions',可以通過受限執行區域輕鬆地防止異步異常。誠然,這將是一個非常深奧的事情要做。 – 2014-06-12 04:41:46