.NET - 检测到ContextSwitchDeadlock

17

我在C#(.NET 3.5 CP, VS2010)中有一个类,执行通常需要很长时间的复杂计算。一分钟后会抛出异常,指出检测到了ContextSwitchDeadlock。由于这个异常是本地化的,用我的非英语语言表达,所以我无法复制粘贴,但其含义如下:

CLR模块不能在60秒内从上下文COM...转换到上下文COM...。拥有目标上下文/公寓的子进程可能正在进行非泵等待或处理非常长时间的操作,而没有泵送Windows系统消息。

基本上,它看起来像我的应用程序正在计算并且长时间未响应Windows,Visual Studio将其关闭并报告可能会死锁。

我尝试做了一些研究,并找到了两种解决方案:

  1. 禁用Visual Studio调试器中的某些选项来检测死锁。对我无效,因为它仅适用于调试目的。

  2. 调用一些DoEvents方法,但它是针对Windows Forms而不是WPF,而我使用的是WPF。

还有建议创建单独的线程,但我完全不了解线程,不知道该怎么做。有什么建议吗?

1个回答

39

这只是来自"托管调试辅助程序"(MDA)的警告。你的代码违反了单线程公寓(STA)线程的一个相当严格的要求,它们不允许长时间阻塞。警告是很真实的,阻塞UI线程很容易导致死锁。但在你的情况中,解释很简单,它变得僵硬是因为正在繁忙地计算,而不是因为它实际上被阻塞。MDA无法区分。

您可以通过"调试+异常"关闭警告,打开"托管调试辅助程序"节点并取消选中"ContextSwitchDeadlock"。

但这仍然会给用户留下一个死亡的窗口,对用户体验来说不是很好。它还可能产生副作用,导致其他程序在发送消息到顶层窗口时变得无响应。

您需要使用线程来真正解决这个问题。看一看BackgroundWorker,它在MSDN Library和许多其他地方都有很好的文档说明。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接