【问题标题】:Monitor.TryEnter AdviceMonitor.TryEnter 建议
【发布时间】:2010-07-30 05:08:05
【问题描述】:

我们在 vb.net 应用程序的一部分中使用并行扩展来从字典(字符串、数据表)中检索数据表。在检索表的方法中,我们使用 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 为假。

【问题讨论】:

  • 字典支持一次从多个线程读取,所以也许你甚至不需要 Monitor 调用(如果你可能同时写,那么你确实需要它,你需要以保护具有相同同步调用的写入)。
  • 是的,我们同时阅读和写作。上面的代码和write函数很相似。

标签: .net multithreading


【解决方案1】:

Monitor.Exit 调用引发了错误。发生的情况是 TryEnter 偶尔超时并且未获取锁,但始终调用 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

【讨论】:

  • 如果您在If Monitor.TryEnter(...) 部分中执行Try/Finally,就像MSDN documentation 中的Monitor.TryEnter 节目一样,您可以保存Boolean
  • @JeffBridgman:是的。但是,我在这里特别选择了这种结构,因为它可以通过在 Try 关键字之前简单地调用 RuntimeHelpers.PrepareConstrainedRegions 来通过受约束的执行区域轻松强化异步异常。诚然,这将是一件非常深奥的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-23
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多