27

我正在运行的大型操作中收到以下消息:

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

如何发送 Windows 消息,以便在长时间操作时不再出现此错误?

4

8 回答 8

21

目前还不清楚上下文是什么——您是否在 WinForms 或 WPF 应用程序的 UI 线程上执行一些长时间运行的任务?如果是这样,请不要这样做 - 使用BackgroundWorker,或直接在线程池或新线程上运行任务(可能使用Control.Invoke/BeginInvokeDispatcher如果您需要更新 UI)。如果你的大操作使用了抱怨的 COM 组件,那就更难了……

于 2011-01-26T16:06:44.430 回答
7

据我所知,这件事只发生在附加的调试器上。您将永远不会在生产中遇到此异常。

于 2011-01-26T16:16:34.387 回答
4

如果在调试器中发生这种情况,可能是由于 ContextSwitchDeadlock MDA,您可以将其关闭(使用 Visual Studio 中的“异常”窗口)。然而,这表明了一个更大的问题——你不应该在你的 UI 线程上执行长时间运行的操作。

于 2011-01-26T16:07:19.373 回答
3

我倾向于在这些场景中使用Application.DoEvents 。我不知道这是否适用于您的情况。它需要对 System.Windows.Forms 的引用,但也可以在控制台应用程序中使用。

或者,您可以尝试多线程您的应用程序。

于 2011-01-26T16:07:05.203 回答
2

传统的win32方法是:

void PumpMessages()
{
    MSG msg;
    for( ;; ) {
        if( !PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) {
            return;
        }
        if( msg.message == WM_QUIT ) {
            s_stopped = true;
            return;
        }
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
}

但我推测您使用的是 .NET。

于 2011-01-26T16:06:57.963 回答
1

我在从 WinForms 项目切换到 ConsoleApp 项目时遇到了这种情况。中的Main()方法有一个WinForms 模板遗留下来Program.cs的不必要的属性。[STAThread]删除属性使错误消失。

于 2020-02-10T23:35:03.263 回答
0

您应该在单独的线程上处理长时间运行的操作,以避免冻结 UI。这也将解决上面的问题

于 2011-01-26T16:06:13.543 回答
0

我知道这是几年前问过的,但希望这会帮助其他人。如果您不想担心做后台工作者或发送消息,一个简单的解决方法就是简单地更新 UI 上的内容。例如,我有一个只有我使用的工具,所以我不在乎它是否使用 UI 线程。因此,我只需将 UI 上的 textbox.text 更新为我正在处理的任何内容。这是代码片段。这是一种非常hacky,并且可能不正确的专业方法,但它确实有效。

for (int i = 0; i < txtbxURL.LineCount; i++)
{
    mytest.NavigateTo(mytest.strURL);
    mytest.SetupWebDoc(mytest.strURL);
    strOutput = mytest.PullOutPutText(mytest.strURL);
    strOutput = mytest.Tests(strOutput);
    mytest.CheckAlt(mytest.strURL);
    mytest.WriteError(txtbxWriteFile.Text);
    txtblCurrentURL.Text = mytest.strURL;
    //This ^^^ is what is being updated, which keeps the thread from throwing the exception noted above.
}
于 2017-11-13T16:01:48.637 回答