注释
本文特定于 .NET Framework。 它不适用于 .NET 的较新版本实现,包括 .NET 6 及更高版本。
contextSwitchDeadlock在尝试的 COM 上下文转换期间检测到死锁时,将激活托管调试助手(MDA)。
症状
最常见的症状是,从托管代码对非托管 COM 组件的调用不返回。 另一种症状是内存使用量随时间推移而增加。
原因
最可能的原因是单线程单元(STA)线程不泵送消息。 STA 线程要么在未泵送消息的情况下等待,要么正在执行冗长的操作,不允许消息队列泵送。
内存使用量随时间推移增加的原因是终结器线程尝试调用 Release 非托管 COM 组件,并且该组件未返回。 这可以防止终结器回收其他对象。
默认情况下,Visual Basic控制台应用程序的主线程的线程模型为 STA。 如果 STA 线程通过公共语言运行时或第三方控件直接或间接使用 COM 互操作性,则会激活此 MDA。 若要避免在Visual Basic控制台应用程序中激活此 MDA,请将MTAThreadAttribute属性应用于主方法或修改应用程序以泵送消息。
如果满足以下所有条件,则此 MDA 可能会被误激活:
应用程序通过库直接或间接地从 STA 线程创建 COM 组件。
应用程序在调试器中停止,用户继续执行应用程序或执行步骤操作。
未启用非托管调试。
若要确定 MDA 是否被误激活,请禁用所有断点,重启应用程序,并允许它在不停止的情况下运行。 如果未激活 MDA,则初始激活可能是 false。 在这种情况下,请禁用 MDA 以避免干扰调试会话。
注释
此 MDA 位于Visual Studio的默认集中。 有关如何禁用 MDA 的信息,请参阅 使用托管调试助手诊断错误。
解决方案
遵循有关 STA 消息泵的 COM 规则。
对运行时的影响
此 MDA 对 CLR 没有影响。 它仅报告有关 COM 上下文的数据。
输出
描述当前上下文和目标上下文的消息。
配置
<mdaConfig>
<assistants>
<contextSwitchDeadlock />
</assistants>
</mdaConfig>