在C#中检测到ContextSwitchDeadlock错误

我正在运行一个C#应用程序,并在运行时,我得到以下错误:

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

任何人都可以请帮我解决这个问题吗?

非常感谢。

程序的主线程正忙于执行代码一分钟。 它没有照顾正常的职责,抽取消息循环。 在工作线程中使用COM服务器时,这是非法的:直到主线程再次空闲时才能调用对其方法的调用。

它应该是显而易见的,你的用户界面应该作为一个门钉死亡。 Windows应该用一个显示“Not Responding”的ghost代替主窗口。 closures窗口将不起作用,没有点击事件有任何效果。

无论你的主线程在做什么,都应该由一个工作线程完成。 BackgroundWorker类是很好的,你会发现MSDN库文章中的许多使用帮助。 如果您不知道主线程正在做什么,请使用Debug + Break All,Debug + Windows + Threads。

还有一个可能的原因:如果使用的是VS2005的RTM版本,请务必安装Service Pack 1。

要查找哪个操作阻止上下文切换,并显示contextSwitchDeadlock MDA ,可以使用以下步骤。 请注意,我将指的是Visual Studio 2012。

  1. 重现错误。 这可能涉及一些试验和错误。
  2. 在显示的托pipedebugging助手中单击“确定”而不是“继续”。
  3. 通过右键单击工具栏停靠区域并select“debugging位置”,确保“debugging位置”工具栏处于活动状态。 如果它处于活动状态,则应该在工具栏中看到一个标记为“线索”的下拉列表。
  4. 主题下拉列表中选定的项目应该是主线程以外的线程,因为它将是一个后台线程,抱怨主线程占用了所有的注意力。 在下拉列表中select主线程。
  5. 您现在应该在代码编辑器中看到阻止上下文切换的代码。

假设您决定不把主要线程中的资源密集型操作移走 – 请在查看其他一些答案和注释之前,您有以下选项来禁用托pipedebugging助手。

在Visual Studiodebugging器中

  1. 在发生错误时,可以在MDA对话框中直接禁用MDA,方法是取消选中“在引发此exceptiontypes时中断”。
  2. exception设置对话框使用MSDN下面的说明。

在debugging菜单上,单击例外。 (如果“debugging”菜单不包含“例外”命令,请单击“工具”菜单上的“自定义”将其添加。)在“例外”对话框中,展开“托pipedebugging助手”列表,然后清除单个MDA的“投掷”checkbox。

在Visual Studiodebugging器之外

  1. registry项 (机器范围,受影响的所有MDA)
  2. 环境variables (机器宽度,可以指定MDA)
  3. 应用程序configuration设置 (应用程序范围,可以指定MDA)

注意:前两个选项之一必须设置为1才能有效。

在我的情况下,问题是调用控制台应用程序中entity framework中的ObjectContext.SaveChanges() 。 通过将MTAThreadAttribute应用于Main()方法,不再引发ContextSwitchDeadlockexception 。 我不幸地不确定这种变化的全部影响。

此消息表明您的某些代码正在尝试切换线程,并且目标线程正忙。 例如,后台线程尝试调用UI线程的调用来更新UI,而UI正在运行一段时间的紧密循环。

要真正弄清楚发生了什么,你需要打入debugging器,看看所有的线程和他们在做什么。

在某些情况下:
debugging – >例外 – >pipe理debugging助手
并取消选中ContextSwitchDeadlock项目。

只需从Visual Studio 2005窗口的Debug菜单中selectExceptions,Edxception对话框将popup,selectManaged Debugging Assistants Exception节点,然后selectContextSwitchDeadlock并从Thrown列中删除select。 这将停止vs抛出ContextSwitchDeadlockexception。

希望这可以帮助..

我遇到了这个问题,当我试图找出为什么我的OracleDataReader抛出一个exception。 我认为这是因为它被赋值为null因为exception是与一个参数是null。 所以我做了:

 while (dr.Read()) { while (dr != null) // <-- added this line { ... 

原来dr从来没有null,所以循环一直持续直到这个消息到达,继续,因为你可以点击“继续”继续下去,直到你用完内存(不要这样做 – 点击“确定”)。 因此,故事的道德,寻找内存泄漏,是从数据库stream入数据到内存循环到无限。 该错误实际上是试图警告你一个不好的情况。 最好听从它。

这个错误对我来说是无数次的,我将其追溯到DataGridViewRow一个迭代中,在该迭代中,我将checkbox的值设置为true。 由于我在debugging模式下运行,所以我可以select继续,所以我能够做到这一点。

我希望这可以帮助别人。