【发布时间】:2018-04-01 21:28:19
【问题描述】:
这是一个我正在修复的大型多线程项目(不是我写的)。该应用程序挂在我正在追踪的一些锁上。
我检查并用Monitor.TryEnter 替换了所有“锁定”语句,这样我就可以设置等待期。我偶尔会遇到Monitor.Exit 的异常。
原来的样式是
private List<myClass> _myVar= new List<myClass>();
if (_myVar != null)
{
lock (_myVar)
{
_myVar = newMyVar; // Where newMyVar is another List<myClass>
}
}
我把上面所有的锁都换成了:
if (_myVar != null)
{
bool lockTaken = false;
try
{
Monitor.TryEnter(_myVar, new TimeSpan(0, 0, 5), ref lockTaken);
if (lockTaken)
{
_myVar = newMyVar; // Where newMyVar is another List<myClass>
}
}
finally
{
if (lockTaken) Monitor.Exit(_myVar);
}
}
我得到的例外是
SynchronizationLockException 对象同步方法被调用 来自不同步的代码块
。如果是这样,为什么原来的lock语句也不抛出异常?
将Monitor.Exit 放在try catch 中是否安全,如果出现异常则忽略它?
【问题讨论】:
-
你有没有机会在你的新定制锁里做任何
awaiting? -
你确定这是一个正在抛出而不是说脉冲的出口吗?
-
你的问题有点不清楚。将所有锁更改为超时锁是为了尝试诊断 问题还是修复 问题?无论哪种方式,这都是一个有问题的技术,但是当你不清楚你在做什么时,很难给你建议。
-
啊,你的编辑让一切变得不同。 原始代码完全错误。它永远不会可靠地工作。想象一下,你走进浴室,锁上门,当你在里面时建造第二扇门并保持打开状态,然后你想知道为什么有时会有两个人在里面洗手间。 永远不要在锁中锁定您正在修改的变量。这是一件完全疯狂和错误的事情。
-
写这个“大型多线程程序”的人连关于锁的最基本知识都不懂,结果可能是一团糟。无法立即看出问题所在这一事实意味着您对锁的了解不够充分,无法正确修复它。
标签: c# synchronization