Visual Studio:ContextSwitch死锁


167

我收到了我无法解决的错误消息。它源自Visual Studio或调试器。我不确定最终的错误情况是在VS,调试器,我的程序还是数据库中。

这是Windows应用程序。不是网络应用。

VS发出的第一条消息是一个弹出框,上面显示:“没有为任何调用堆栈框架加载任何符号。无法显示源代码。” 单击该按钮后,我得到:“ 检测到ContextSwitchDeadlock ”,以及下面复制的一则长消息。

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

该错误似乎与过程运行多长时间(即60秒后)有关,而不是与发现多少错误有关。我不认为这是内存问题。循环内未声明任何变量。唯一创建的对象是SqlDataReaders,它们位于Using结构中。添加System.GC.Collect()无效。

该数据库是同一台便携式计算机上的SqlServer站点。

表单上没有精美的小玩意或小工具。

我不知道此过程中的任何事情与我之前数十次所做的事情有很大不同。我之前已经看过错误,但是从来没有始终如一。

有什么想法吗?

完整错误文本: 60秒钟以来,CLR无法从COM上下文0x1a0b88过渡到COM上下文0x1a0cf8。拥有目标上下文/公寓的线程很可能要么执行非泵送等待,要么处理很长时间运行的操作而不泵送Windows消息。这种情况通常会对性能造成负面影响,甚至可能导致应用程序变得无响应或随着时间的推移不断累积内存使用量。为避免此问题,所有单线程单元(STA)线程都应使用泵送等待原语(例如CoWaitForMultipleHandles),并在长时间运行的操作中定期泵送消息。

Answers:


287

ContextSwitchDeadlock并不一定意味着你的代码中有一个问题,只是有一个潜在的。如果转到Debug > Exceptions菜单中并展开Managed Debugging Assistants,则会发现ContextSwitchDeadlock已启用。如果禁用此选项,则当项目需要很长时间才能处理时,VS将不再发出警告。在某些情况下,您可能会有效地长时间运行。如果您正在调试并且在处理过程中停在一条线上,这也很有用-在您有机会深入探讨问题之前,您不希望它抱怨。


4
对!谢谢。我确实必须转到“自定义”并将“例外”添加到“调试”菜单。不是用户界面最直观的方面。工具\自定义,然后重新排列命令(按钮),然后从右上角的下拉菜单中选择调试,然后添加(按钮)。ew!
SeaDrive

81
ctrl-alt-e带来异常对话框。
Florian Doyon 2012年

1
Visual Studio的许多最新版本(2012、2010、2008)以及可能更早的版本,允许人们在安装后首次运行时选择Visual Studio的主要用途。该选择决定了工具栏的默认布局,包括哪些控件是可见的或隐藏的,甚至是哪些击键对应于哪些命令。在VS 2010中,“导入和导出设置向导”允许您重置为可用默认值之一。
Zarepheth 2013年

4
@ B.ClayShannon-ContextSwitchDeadlock特定于调试器。exe的发行版将不会显示此消息。
Pedro

9
在VS 2013中,使用导航Debug -> Windows -> Exceptions Settings。然后使用搜索
Markus Weber

16

正如Pedro所说,如果您单步执行代码,调试器会阻止消息泵,这是一个问题。

但是,如果要在UI线程上执行长时间运行的操作,请调用Application.DoEvents(),该方法显式地泵送消息队列,然后将控制权返回给当前方法。

但是,如果这样做,我建议您看一下设计,以便您可以在UI线程外执行处理,以使UI保持美观和活泼。


14

听起来您正在应用程序的主UI线程上执行此操作。UI线程负责在到达时泵送Windows消息,但是由于您的消息在数据库调用中被阻止,因此无法这样做。这可能会导致系统范围内的消息出现问题。

您应该查看生成后台线程以进行长时间运行的操作,并在发生这种情况时为用户设置某种“我很忙”对话框。


13

在Visual Studio 2017中,通过以下方式取消选中ContextSwitchDeadlock选项:

调试> Windows>例外设置

在此处输入图片说明

在“异常设置Windows”中:取消选中ContextSwitchDeadlock选项

在此处输入图片说明


9

如果您不想禁用此异常,则您需要做的就是让您的应用程序至少每60秒发送一次某些消息。这将防止发生此异常。尝试不时调用System.Threading.Thread.CurrentThread.Join(10)。您还可以执行其他呼叫,以使消息激增。


您能解释一下为什么有帮助吗?

这将行不通,我有一个循环更新UI并仍然收到错误消息。
htm11h

1
不需要使用10毫秒的值,实际上,如果您打算在长时间运行的操作中反复调用它,则会大大降低整体性能(总时间执行)。只需将零传递给它即可。
ElektroStudios

我有类似的问题。发现您的解决方案正在工作。谢谢!
Sk Shahnawaz-ul Haque

2

上面的解决方案在某些情况下是好的,但是在另一种情况下,当您进行单元测试时,如果您的解决方案未设置为“调试”,则尝试从“测试资源管理器”中“调试选定的测试”会发生这种情况。

在这种情况下,您需要将解决方案从“发行版”更改或将其设置为“调试”。如果这是问题所在,那么更改“ ContextSwitchDeadlock”将不会真正帮助您。

我自己很想念这个,因为错误消息是如此令人讨厌,以至于我没有检查明显的东西是Debug设置!


1

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

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

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

Ctrl + D,E

最好。


0

您可以通过取消选中contextswitchdeadlock从

调试->异常...->展开MDA节点->取消选中-> contextswitchdeadlock


0

我收到此错误,并将查询切换为异步(await(...)。ToListAsync())。现在一切都好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.