1

观察以下伪:

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()s 是 WaitHandle。

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

4

3 回答 3

1

你确定你陷入僵局吗?在 .NET 2.0 中,ThreadPool 终止进程中未处理的异常。

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

于 2009-02-20T12:43:29.300 回答
0

任何阻塞操作都是潜在的死锁。有一些方法可以最大限度地减少或几乎消除死锁发生的机会(如果您始终确保同步操作在有限的时间内完成),但在一般情况下,您不能只假设有一种安全的方法防止死锁。

超时在确保您的应用程序不会死锁方面大有帮助,但是您会遇到停顿,并且您需要以一种特殊的方式从超时中恢复。相同的程序流程不再适用。

如果您有抛出异常的线程,请检查 Visual Studio 中的“调试”>“输出”窗口,即使调试器在处理多个线程时无法中断,它似乎总是会捕获异常。

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

于 2009-02-20T06:35:43.987 回答
0

您可能想查看MSDN上的一个自定义CLR 主机, Joe Duffy开发该主机以提供自动死锁检测。

于 2009-02-20T15:37:41.177 回答