Visual Studio:ContextSwitchDeadlock

我一直在收到一个我无法解决的错误消息。 它来自Visual Studio或debugging器。 我不确定最终的错误条件是在VS,debugging器,我的程序还是数据库中。

这是一个Windows应用程序。 不是一个Web应用程序。

来自VS的第一条消息是一个popup框:“任何调用堆栈帧都不加载符号,源代码不能显示”。 当点击它时,我得到:“ 检测到ContextSwitchDeadlock ”,以及下面转载的长信息。

该错误出现在扫描DataTable的循环中。 对于每一行,它使用表中的一个键(HIC#)作为SqlCommand的参数。 该命令用于创build返回一行的SqlDataReader。 数据进行比较。 如果检测到错误,则将行添加到第二个DataTable。

该错误似乎与程序运行多长时间(即60秒后)有关,而不是发现多less错误。 我不认为这是一个记忆问题。 循环内没有声明variables。 唯一创build的对象是SqlDataReaders,它们在Using结构中。 添加System.GC.Collect()没有效果。

db是同一台笔记本电脑上的SqlServer站点。

表格上没有花哨的小玩意或小玩意儿。

我不知道这个过程中的任何事情,与我以前做过的几十次大不相同。 我以前看过错误,但从来没有一致的基础。

任何想法,任何人?

完全错误文本: CLR已经无法从COM上下文0x1a0b88转换到COM上下文0x1a0cf8达60秒。 拥有目的地上下文/公寓的线程很可能是在不抽取Windows消息的情况下进行非抽取等待或处理非常长的运行操作。 这种情况通常会对性能产生负面影响,甚至可能导致应用程序无响应或内存使用量不断累积。 为了避免这个问题,所有的单线程单元(STA)线程应该使用抽取等待原语(比如CoWaitForMultipleHandles),并在长时间运行的操作中定期抽取消息。

ContextSwitchDeadlock并不一定意味着你的代码有问题,只是有潜力。 如果你去菜单中Debug > Exceptions ,并展开Managed Debugging Assistants ,你会发现ContextSwitchDeadlock被启用。 如果你禁用了这个function,当物品需要很长时间处理时,VS不会再提醒你。 在某些情况下,您可能会有效地进行长时间的操作。 如果您正在debugging并且在正在处理的过程中停下来,这也很有帮助 – 在您有机会深入研究问题之前,您不希望发生抱怨。

正如Pedro所说的,如果您正在逐步完成代码,那么debugging器会阻止消息泵。

但是,如果您正在UI线程上执行长时间运行的操作,请调用明确抽取消息队列的Application.DoEvents(),然后将控制返回到当前方法。

但是,如果你这样做,我会build议在看你的devise,以便您可以执行处理的UI线程,使您的用户界面保持良好和活泼。

这听起来像你在应用程序的主UI线程上这样做。 UI线程负责在到达时泵送Windows消息,但是由于您的数据库调用被阻止,所以无法这样做。 这可能会导致系统信息的问题。

你应该看看为长期运行的操作产生一个后台线程,并为用户提供某种“我很忙”的对话框。

如果您不想禁用此exception,则只需让应用程序每60秒钟至less抽出一次消息即可。 这将防止这种exception发生。 尝试调用System.Threading.Thread.CurrentThread.Join(10)偶尔。 还有其他的电话你可以做,让消息泵。

上面的解决scheme在某些情况下是好的,但还有另外一种情况,在unit testing时发生这种情况,并且当您的解决scheme未设置为Debug时,尝试从“testing资源pipe理器”debugging“选定的testing”。

在这种情况下,您需要从Release中更改解决scheme,或者在此情况下将其设置为Debug。 如果这是问题,那么更改“ContextSwitchDeadlock”不会真的帮助你。

我错过了这个自己,因为错误消息是如此讨厌,我没有检查这是debugging设置的显而易见的事情!

在Visual Studio 2017西class牙语版本中。

“Depurar” – >“Ventanas” – >“Configuraciónde Excepciones”

并search“ContextSwitchDeadlock”。 然后,取消选中它。 或者捷径

按Ctrl + d,E

最好。

你可以通过取消选中contextswitchdeadlock来解决这个问题

Debug-> Exceptions … – >展开MDA节点 – >取消选中 – > contextswitchdeadlock