【问题标题】:The CLR has been unable to transition from COM context [...] for 60 secondsCLR 无法从 COM 上下文转换 [...] 60 秒
【发布时间】:2011-02-14 10:19:39
【问题描述】:

我在以前可以工作的代码上收到此错误。我没有改代码。

这是完整的错误:

CLR 在 60 秒内无法从 COM 上下文 0x3322d98 转换到 COM 上下文 0x3322f08。拥有目标上下文/单元的线程很可能要么进行非泵送等待,要么处理非常长时间运行的操作而不泵送 Windows 消息。这种情况通常会对性能产生负面影响,甚至可能导致应用程序变得无响应或内存使用量随着时间的推移不断累积。为避免此问题,所有单线程单元 (STA) 线程都应使用泵送等待原语(例如 CoWaitForMultipleHandles)并在长时间运行的操作期间定期泵送消息。

这是导致它的代码:

var openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
openFileDialog1.DefaultExt = "mdb";
openFileDialog1.Filter = "Management Database (manage.mdb)|manage.mdb";

//Stalls indefinitely on the following line, then gives the CLR error
//one minute later.  The dialog never opens.
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
    ....
}

是的,我确定对话框没有在后台打开,不,我没有任何明确的 COM 代码或非托管编组或多线程。

我不知道为什么 OpenFileDialog 无法打开 - 有什么想法吗?

【问题讨论】:

  • 我从未见过没有星号的过滤器。试试"Management Database (*.mdb)|*.mdb" 我不知道这是否会混淆框架中的某些内容。
  • @Aaron:正如我所说,它就在昨天起作用。我只是在寻找具有该特定名称的特定文件
  • 这不是错误,而是调试器警告。由 ContextSwitchDeadlock 托管调试助手生成,旨在警告由于 COM 封送处理可能导致的死锁。 OpenFileDialog 使用了大量的 COM。你只有在调试你的应用程序时才会得到它。网络超时时间很长,您必须等待一段时间才能引发真正的异常。
  • 这个异常怎么不是错误?在我的情况下,在长时间运行的操作中使用相同的文本引发异常并且永远不会完成操作。

标签: c# .net


【解决方案1】:

因此,即使您没有明确使用 COM,它也会抱怨 COM 上下文,因为在所有可爱的 C# 代码下打开了一个本机 shell 对话框,而 shell 确实使用了 COM。

此消息告诉您的是,无论它试图做什么,它都是在 UI 线程上执行的,而且方式不是很好,而且这似乎需要很长时间。显然,任何问题本身都不是你的错,所以你可以忽略它给你的大部分建议。

要尝试的事情:

  1. 首先,按照AaronLS 的建议,我会尽量简化您的openFileDialog。尽量不要设置任何东西;只需创建一个新人并致电ShowDialog()。如果这解决了问题,那么你只是给了它格式错误的参数,我们可以去谈谈它的含义。但是,如果它不起作用,则意味着贝壳地出了问题。

  2. 可能发生这种情况的一个可能原因是您安装了一个外壳扩展,该扩展正在做一些坏事。您最好的做法是break-in (ctrl+break in Visual Studio 我认为,或菜单栏上的debug->break all)并为我们获取完整的堆栈。当对话框出现时,我们应该能够通过查看堆栈中的人来识别罪魁祸首。

【讨论】:

    【解决方案2】:

    想通了 - 每次对话框打开时,它都会自动将您带到您上次查看的位置。如果该位置是不再存在的网络位置(例如另一台计算机已关闭),它将永远挂起。

    我的解决方法如下所示:

    string initialDirectory = ...; //Figure out an initial directory from somewhere
    openFileDialog1.InitialDirectory = !Directory.Exists(initialDirectory)
                                           ? Path.GetPathRoot(Environment.SystemDirectory)
                                           : initialDirectory;
    

    【讨论】:

      【解决方案3】:

      解决此问题的一个方法是转到 Visual Studio 中的 Debug -> Exceptions -> Managed Debug Assistants 菜单并取消选中 ContextSwitchDeadlock

      来自http://blog.wpfwonderland.com/2007/08/16/clr-has-been-unable-to-transition-from-com-context-for-60-seconds/

      更新:请不要投反对票,如果您认为这种解决方法是个糟糕的主意。许多人尝试了此处列出的许多解决方案作为答案,但我的解决方法是唯一对他们有帮助的方法。这就是为什么答案仍然是肯定分数的原因。

      【讨论】:

      • 隐藏异常并不意味着它已经消失了!
      • 这是一个糟糕的想法。
      • 丹,你能解释一下,为什么它很糟糕吗?
      • 虽然我通常同意吞下异常是一种不好的做法,但我只是遇到了这个线程,试图解决这个问题。该解决方案适合我的需求。不要假设每个人都在构建一个 200 万行代码的业务应用程序——有时在像我这样的情况下,我只是在编写一个小型数据迁移工具,我并不关心我的 UI 是否更新。这个解决方案让我的程序可以不受阻碍地运行,现在我可以回到床上等待早上完成。
      • 这不是解决方案...这是一种隐藏问题的方法,这绝不是一个好主意。
      【解决方案4】:

      我也遇到了这个问题,我通过将我的 .Net 框架更改为最新的框架(在我的情况下为 .Net 框架 4.5;来自项目属性 Window-> Debug-> .Net Framework),并将 CPU 类型从 x86 更改为 Any CPU(在项目属性 Window-> Build-> Platform Target 中)。 p>

      【讨论】:

      • 试过了,如果你在 64 位机器上,这很有意义,但不幸的是,这对我没有任何解决。 VS 2013 Premium/Windows 10,我正在为 Excel 2016 编写 VSTO 加载项。
      【解决方案5】:

      我在处理大型数据库时遇到了这个问题,它使 UI 冻结了很长时间。所以我把代码放在BackgroundWorker 中,现在问题就解决了。感谢@i_am_jorf

      这条消息告诉你的是,无论它试图做什么, 它是在 UI 线程上做的,而不是以一种好的方式,这似乎 需要很长时间。

      private void btnConvert_Click(object sender, EventArgs e)
      {
        Cursor = Cursors.WaitCursor;
        bgwConvert.RunWorkerAsync();
      }
      
      private void bgwConvert_DoWork(object sender, DoWorkEventArgs e)
      {
        //My taking-lots-of-time codes
      }
      
      private void bgwConvert_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
      {
        Cursor = Cursors.Default;
        MessageBox.Show("Done");
      }
      

      【讨论】:

        【解决方案6】:

        我刚才也遇到了同样的问题,我的解决方案很简单: 清理解决方案并重建它!

        我正在使用 Visual Studio 2015。

        希望这篇文章有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-06-19
          • 2017-04-03
          • 2011-08-17
          • 2020-06-14
          • 1970-01-01
          • 2015-11-05
          相关资源
          最近更新 更多