CLR无法从COM上下文转换60秒

时间:2010-04-30 21:52:12

标签: c# .net

我在以前的代码上遇到此错误。我没有改变代码。

以下是完整错误:

  

CLR无法从COM上下文0x3322d98转换到COM上下文0x3322f08达60秒。拥有目标上下文/公寓的线程很可能是在非抽空等待或处理非常长时间运行的操作而不抽取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不会打开 - 任何想法?

6 个答案:

答案 0 :(得分:12)

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

我的解决方法如下:

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

答案 1 :(得分:11)

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

这条消息告诉你的是,无论它想做什么,它都是在UI线程上做的,而不是以一种很好的方式,这似乎需要很长时间。显然,任何错误都不是你自己的错,所以你可以忽略它给你的大部分建议。

要尝试的事情:

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

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

答案 2 :(得分:9)

问题的一个解决方法是转到Debug - >例外 - > Visual Studio中的托管调试助手菜单,取消选中ContextSwitchDeadlock

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

更新:如果您认为合理的解决方法,请不要贬低。许多人在这里尝试了许多解决方案作为答案,但我的解决方法是唯一帮助他们的方法。这就是为什么答案仍然有正面评分。

答案 3 :(得分:7)

我在使用大型数据库时遇到了这个问题,它使用户界面长时间冻结。所以我把代码放在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");
}

答案 4 :(得分:2)

我也有这个问题,我通过将我的.Net框架更改为最新版本来解决它(在我的情况下是.Net框架4.5;来自项目属性 Window-&gt; Debug-&gt; .Net Framework < / em>),并将CPU类型从 x86 更改为任何CPU (在项目属性中 Window-&gt; Build-&gt; Platform Target )。

答案 5 :(得分:2)

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

我正在使用Visual Studio 2015。

希望这个有所帮助。