2011-01-26 76 views
18

我越来越对我运行的大作业以下消息:长时间运行时抽取Windows消息?

的CLR一直无法从COM上下文0x1fe458过渡 到COM 方面0x1fe5c8 60秒。 拥有目的地 上下文/公寓的线程最有可能是 或者执行非泵等待或者 处理非常长的运行 操作而不泵送Windows 消息。这种情况通常具有负面的性能影响,并且可能 甚至导致应用程序变为 非响应或内存使用 随着时间的推移不断累积。为了 避免这个问题,所有的单 单线程单元(STA)线程 应该使用抽水等待基元 (如CoWaitForMultipleHandles)和 在长时间运行 常规操作抽取消息。

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

+0

任何带有完整源代码的最终解决方案? – Kiquenet 2013-04-24 10:26:40

回答

17

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

+0

是的,这是在WinForm中(抱歉没有在OP中指定)。我将尝试在后台工作人员中实现此代码,谢谢! – sooprise 2011-01-26 16:29:26

+0

完成实现这个,像一个魅力工作,再次感谢! – sooprise 2011-01-26 19:31:02

+1

@Jon Skeet您能否详细说明COM组件部分?我们有多个线程访问COM对象,这导致了OP的问题。 – Odys 2012-10-23 11:28:09

0

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

0

传统的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。

3

我倾向于在这些情况下使用Application.DoEvents。尽管如此,我不知道这是否会起作用。它需要对System.Windows.Forms的引用,但也可以在控制台应用程序中使用。

另外,你也可以尝试多线程你的应用程序。

3

如果在调试器中发生这种情况,可能是由于ContextSwitchDeadlock MDA,您可以关闭它(使用Visual Studio中的“例外”窗口)。但是,这表示存在更大的问题 - 您不应该在UI线程上执行长时间运行的操作。

5

因为我知道这件事发生在附加的调试器上。在生产中你永远不会得到这个例外。

0

我知道这是多年前提出的,但希望这可以帮助其他人。如果你不想担心做后台工作,或者抽取消息,一个简单的解决方法就是更新UI上的某些东西。例如,我有一个只有我使用的工具,所以我不在乎它是否使用UI线程。所以我只是简单地将UI上的textbox.text更新为我正在处理的任何内容。这里是代码的一小部分。这是一个非常冒险的,可能不正确的方式来做到这一点专业,但它的作品。

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. 
}