如何安全地使用WaitHandles来防止死锁?

时间:2009-02-20 06:25:13

标签: c# .net asp.net multithreading threadpool

观察以下伪:

ManualResetEvent[] resetEvents = new ManualResetEvent[operations.Count];

for( int i = 0; i < operations.Count; i++ )
{
  resetEvents[i] = new ManualResetEvent(false);
  ThreadPool.QueueUserWorkItem(new WaitCallback(timeConsumingOpHandler), resetEvents[i]);
}

WaitHandle.WaitAll(resetEvents);

如果在其中一个池线程中发生异常,我的ASP.NET WebApp就会死锁。没有异常信息在响应流上传递。 我正在寻求防止这种情况的建议。固定超时是可以接受的。 假设timeConsumingOpHandler Set()是WaitHandle。

整个timeConsumingOpHandler被包装在try-catch-finally块中,其中WaitHandle在finally部分期间是Set()。尽管如此,发生了死锁。

3 个答案:

答案 0 :(得分:1)

你确定你陷入僵局吗?在.NET 2.0中,ThreadPool terminate the process中的未处理异常。

您不应在ASP.NET应用程序中使用ThreadPool。 ASP.NET本身使用ThreadPool来处理请求,因此您正在竞争同一组线程。如果必须执行异步,请使用异步委托。

答案 1 :(得分:0)

任何阻塞操作都是潜在的死锁。有一些方法可以最小化或几乎消除发生死锁的可能性(如果你总是确保你的同步操作在有限的时间内完成),但在一般情况下,你不能只假设有一个安全的方法来防止死锁。

超时在确保您的应用程序没有死锁方面有很长的路要走,但是您将会停滞不前,并且需要以特殊的方式从超时中恢复。相同的程序流程不再适用。

如果你有线程抛出异常,请检查Debug&gt; Visual Studio中的输出窗口似乎始终捕获异常,即使调试器在处理多个线程时未能中断。

看起来你正在将工作拆分为单独的线程,以实现并行性。为什么在ASP.NET应用程序中需要它?

答案 2 :(得分:0)

您可能希望在CLR host开发的MSDN上查看自定义Joe Duffy以提供自动死锁检测。