[英]WPF in WinForms: blocked on Dispatcher.Invoke although UI thread alive
我們在WinForms控件中嵌入了一個WPF控件,該控件又作為ActiveX控件公開。 此ActiveX最終用於由第三方開發的C ++應用程序中。
在某些時候,ActiveX控件的UI變得凍結,而其余的C ++應用程序運行正常。 經過一些調試后,我注意到每次調用Application.Current.Dispatcher.Invoke時都阻止了WPF控件。 但是,WinForms控件處理它的Control.Invoke調用就好了。 每當我暫停調試器時,我都可以看到UI線程在C ++應用程序中做了一些工作,但似乎沒有阻塞或等待任何事情。 這就好像UI線程突然並且莫名其妙地拒絕執行WPF委托。
當C ++應用程序在很長一段時間(幾分鍾)內獨占UI線程時,WPF控件有時會進入此狀態。 我要做的第一件事就是使用不同的線程進行這樣一個耗時的任務,但正如我已經說過的那樣,我不負責C ++應用程序正在做什么。 無論如何,這不是我的WPF控件以這種方式運行的原因。 我不知道如何解決這個問題; 任何幫助,將不勝感激。
我建議運行MS Debug Diagnostics Tool - http://support.microsoft.com/kb/2580960 。
我們已經有了很好的結果來識別COM互操作阻塞問題,在我們的例子中,這是一個掛起的COM終結器阻塞垃圾收集。 您可以在各種模式下運行它,但是當使用.NET分析運行時,它將突出顯示終結器隊列等的任何問題。運行起來有點笨拙,但它給你的信息是黃金。
Invoke
的問題在於它就像一個多線程調用; 但事實並非如此, Invoke
正在阻止 - 你仍然只是一次讓一個線程。 Invoke
確實只是確保在UI線程上執行操作。 這是通過將消息強制轉換為消息泵並以此方式執行來完成的。 對於調用Invoke
的線程需要執行的操作可能會阻止該操作以繼續操作。 例如:
lock(someLock)
{
dispatcher.Invoke(SomeMethod);
}
//...
public void SomeMethod()
{
lock(someLock)
{
//... do some work here
}
}
在此示例中, Invoke
被阻止在持有鎖時調用SomeMethod
。 但是, SomeMethod
想要相同的lock
所以它被阻止等待lock
。 你有一個僵局。
我建議改用BeginInvoke
。
我不確定這是你的問題,因為你沒有提供任何代碼; 但這是Invoke
的一個非常常見的問題。 通常沒有理由需要Invoke
; 如果您認為有需要,那通常表明存在問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.