.net CLR在60秒内无法从COM上下文[...]转换

s4chpxco  于 2023-05-19  发布在  .NET
关注(0)|答案(6)|浏览(840)

我得到这个错误的代码,用来工作。我没有改变代码。
以下是完整的错误:
CLR在60秒内无法从COM上下文0x 3322 d98转换到COM上下文0x 3322 f08。拥有目标上下文/单元的线程很可能正在执行非泵送等待或处理一个非常长的运行操作而不泵送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打不开-有什么想法吗?

0x6upsns

0x6upsns1#

解决这个问题的一个方法是转到VisualStudio中的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/

更新2. Visual Studio 2019+:

调试-> Windows ->异常设置
取消选中上下文切换死锁

oxalkeyp

oxalkeyp2#

想通了-每次对话框打开时,它都会自动带你到你最后看过的位置。如果该位置是不再存在的网络位置(例如另一台计算机关闭),它只会永远挂起。
我的解决方法如下:

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

yzxexxkh3#

所以,它抱怨COM上下文,即使你没有显式地使用COM,因为在所有可爱的C#代码下面打开一个本地shell对话框,而shell确实使用COM。
这条消息告诉你的是,无论它试图做什么,它都是在UI线程上做的,而且不是以一种好的方式做的,这似乎需要很长时间。很明显,无论是什么错误都不是你的错,所以你可以忽略它给你的大部分建议。
可以尝试的事情:
1.首先,我会像AaronLS建议的那样,尽可能地简化openFileDialog。试着不要设置任何东西;只需创建一个新对象并调用ShowDialog()。如果这解决了问题,那么你只是给了它畸形的参数,我们可以讨论它的含义。然而,如果它不起作用,这意味着在shell土地上出了问题。
1.发生这种情况的一个可能原因是您安装了一个正在做坏事的shell扩展。最好的方法是break-in (ctrl+break in Visual Studio,或者菜单栏上的debug->break all),然后为我们获取完整的堆栈。当对话框出现时,我们应该能够通过查看谁在堆栈上来识别罪魁祸首。

htzpubme

htzpubme4#

我在使用大型数据库时遇到了这个问题,它使UI冻结了很长一段时间。所以我把代码放在BackgroundWorker中,现在问题解决了。感谢@i_am_约尔夫
这条消息告诉你的是,无论它试图做什么,它都是在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");
}
sgtfey8w

sgtfey8w5#

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

fhity93d

fhity93d6#

我刚刚遇到了同样的问题,在我的情况下,解决方案很简单:清洗溶液并重建它!
使用Visual Studio 2015。

相关问题