【发布时间】:2011-06-20 19:56:22
【问题描述】:
我在代码中有一个关键部分,它由两个函数调用分隔,比如Start() 和End()。他们使用Monitor 在执行期间阻塞其他线程。现在我的问题是,如果某个线程由于某种原因没有调用End(),那么我的整个进程就有麻烦了,因为每个线程都在等待这个Monitor 被释放。
当然我可以使用带超时的TryEnter,这样我就不会永远等待,但这不会释放被阻止的Monitor,所以我的程序从这个时候开始每次都会进入这个超时。
如果给定的超时结束,有没有办法从另一个线程释放阻塞的Monitor?
void Start(){ Monitor.Enter(obj); }
void End(){ Monitor.Exit(obj); }
编辑:
我们通过 com interop 调用 Excel,我们无法确定 Excel 进程是否始终按预期工作。请注意,这是一个 Web 应用程序,因此无法处理这种情况是致命的。第一次调用Start(),请求调用excel函数,请求结束调用End()。 excel进程总是有可能开始挂起。
EDIT2: 我现在有了将 ent 锁的所有者存储在变量中的想法,并且在死锁时我可以杀死这个线程。这不会释放锁吗?
if (Monitor.TryEnter(excelLocker, 10000) == false)
{
excelOwner.Abort();
excelOwner = null;
}
else
{
excelOwner = Thread.CurrentThread;
}
【问题讨论】:
-
为什么不在你的方法中设置一些东西来简单地 while(...) 直到达到某个阈值然后在那一刻爆发?
-
不要试图修补代码中的错误。修复错误。
-
@Hans Passant:这不是为了修复我们的错误。我们通过 com interop 调用 Excel,我们无法确定 Excel 进程是否始终按预期工作。请注意,这是一个 Web 应用程序,因此无法处理这种情况是致命的。
-
@Aaron:你的意思是使用轮询而不是适当的锁定?
-
基本上将其分解为典型的异步行为;所有异步操作都是相同的,因为您不知道它何时会返回。有了这个在你的应用程序中构建了一个关于所有异步操作的超时机制,如果在给定的阈值内没有收到返回,一种方法是轮询。
标签: .net multithreading locking deadlock