17

我在 c#(.net 3.5 cp,vs2010)中有一个类,它执行通常需要很长时间的复杂计算。一分钟后抛出异常,检测到 ContextSwitchDeadlock。例外是本地化的,针对我的非英语语言,所以我无法复制粘贴,但含义如下: ¨ CLR 模块无法从上下文 COM ... 转换到上下文 COM ... 60 秒。拥有目标上下文/单元的子进程可能正在执行非泵送等待或处理非常长时间运行的操作而不泵送 Windows 系统消息。

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

我试图做一些研究并找到了两个解决方案:

  1. 禁用 Visual Studio 调试器中的某些选项以检测死锁。不要为我工作,因为它仅用于调试目的。

  2. 调用一些 DoEvents 方法,但它是用于 Windows 窗体而不是 WPF,我正在使用 WPF。

还有人建议创建单独的线程,但我对线程完全陌生,不知道我该怎么做。请问有什么建议吗?

4

1 回答 1

39

这只是来自托管调试助手 (MDA) 的警告。您的代码违反了对单线程单元 (STA) 线程的严格要求,它们不允许长时间阻塞。警告足够真实,阻塞UI线程很容易导致死锁。但是您的情况的解释很简单,它只是因为忙于计算而变得紧张,而不是因为它实际上被阻塞了。MDA 无法区分。

您可以使用 Debug + Exceptions 关闭警告,打开 Managed Debugging Assistants 节点并取消选中 ContextSwitchDeadlock。

这仍然会在用户的桌面上留下一个对世界来说已经死去的窗口,这并不是一个很好的用户体验。它可能会产生副作用,导致其他程序在向顶级窗口发送消息时变得无响应。

你确实需要使用线程来真正解决这个问题。看看 BackgroundWorker,它在 MSDN Library 和许多其他地方都有很好的记录。

于 2011-11-12T17:38:11.430 回答