2011-01-26 73 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. 
}