2011-03-04 32 views
3

背景:我的同事和我正在維護我們繼承的一百萬行遺留應用程序。它的前端是使用VB6編寫的,而且我們幾乎將所有資源都用於將其轉換爲C#,因此我們正在尋找針對特定問題的快速&髒解決方案。使用SetParent竊取另一個進程的主窗口,但保持消息循環分離

該應用程序以插件方式運行。有多達20個單獨的ActiveX控件可以一次加載爲網格式佈局。問題在於ActiveX控件在自己的UI線程上完成了所有的處理,並且由於很多阻止等待網絡訪問,UI變得非常糟糕。當我們的託管C#應用程序加載這些控件時,由於有多少控件咀嚼UI資源無所事事,它變得無響應。最重要的是,這些控件是脆弱的,會在最輕微的挑釁時崩潰。當它們在主C#應用程序中託管時,會造成嚴重的不穩定。

到目前爲止,我最好的同事正在爲每個ActiveX控件啓動一個進程。這個我們稱之爲代理的進程是另一個winforms應用程序。它使用命名管道與主機進程進行通信。宿主進程創建一個窗口,加載我們選擇的ActiveX控件(通過一些反射& AxHost魔術),並通過命名管道告訴主進程它的窗口句柄。主進程使用SetParent和SetWindowPos的組合來將代理應用程序移入自身以模擬插件。大小更新通過命名管道發送。

直到ActiveX應用程序做了一些冗長的過程,我們在主窗口上工作時點擊左右,這種方式運行得很好。一段時間以來,主窗口是響應式的,但最終它變得沒有響應,因爲子窗口等待其UI線程。我們如何在保持SetParent的優點的同時,讓子窗口保持自己的完整線程?

(請讓我知道如果有什麼不清楚的!)

+1

這聽起來真的是一個好時機下車趾高氣揚,只是實現它作爲一個本機Win32應用程序託管你在哪裏得到很好地控制所有這些問題, – 2011-03-05 06:50:06

+0

@ChrisBecke:* 「你可以很好地控制所有這些問題」 - 不,你不知道。這些規則是一成不變的,你無法做任何改變。 (好吧,你*可以*向Microsoft提交一個設計變更請求,並要求他們爲你重寫窗口子系統。)你可以在線程間調用SetParent來附加這些線程的輸入隊列。這不是編程語言或運行時環境的問題。 – IInspectable 2016-10-30 01:50:55

回答

5

我以前做過這個。它變得混亂。

我們在自己的AppDomain中運行了每個插件,它啓動了它自己的UI線程。我們在遇到很多真正討厭的問題後做了這個,當我們沒有使用不同的UI線程。

這確實意味着您有跨AppDomains進行通信的所有痛苦,但這是可行的。最主要的是你需要在每個AppDomain /插件中運行Application.Run。在他們之間進行大量的關懷溝通 - 即使關閉也很棘手。

祝你好運:)

+0

作爲代理(子)應用程序的一部分,我們使用了Application.run(新的Form1())[或多或少]。啓動的窗口是完全獨立的可執行文件,顯示在任務管理器和所有內容中。當我們SetParent時,他們仍然鎖定我們的UI線程。 :( – 2011-03-04 15:18:51

+0

@insta:嗯,這聽起來很奇怪,如果你打入調試器,它會阻塞什麼? – 2011-03-04 15:21:31

+0

@insta:當你調用[AttachThreadInput](https://msdn.microsoft.com)時,會出現這種情況。 COM/EN-US /庫/窗/臺式機/ ms681956。aspx)(跨越線程邊界的'SetParent'),因爲[AttachThreadInput就像是採用兩個線程並將他們的資金彙集到一個聯合銀行賬戶中,雙方需要在場才能提取任何資金](https:// blogs.msdn.microsoft.com/oldnewthing/20130619-00/?p=4043)。噢,[擁有跨進程父/子或擁有者/擁有的窗口關係是合法的嗎?](https://blogs.msdn.microsoft.com/oldnewthing/20130619-00/?p=4043) – IInspectable 2016-10-30 01:36:18

相關問題