簡體   English   中英

接口在多線程C#應用程序中凍結

[英]Interface freezes in multi-threaded c# application

我有一個ac#.NET多線程應用程序,該應用程序凍結了接口。 與此不同的是,除非我讓系統閑置足夠長的時間以使屏幕保護程序能夠啟動,否則接口不會凍結(這需要我重新輸入密碼才能重新獲得對系統的訪問權限)。 當界面再次變得可見時(在我成功輸入密碼之后),界面被鎖定。 只要我不啟動屏幕保護程序,該界面就不會鎖定。

我應該指出,我有兩個訪問同一個dll的不同可執行文件,無論我使用哪個應用程序訪問DLL,都會出現此問題。 這似乎暗示問題出在DLL中,因為兩個應用程序(C ++ / MFC)和(C#/。NET)完全不同,除了它們與DLL的關系如何。

兩個exe在與DLL交互的方式上執行相似的步驟。 他們調用dll來設置串行端口通信,在DLL中打開一個狀態窗口,在DLL中啟動一個線程以監視通訊端口,然后在主應用程序中啟動一個線程來監視dll中的堆棧。

當DLL中的線程從通訊端口獲取數據時,將對其進行解析,並將其結果放入堆棧中,然后通過委托將其發布到狀態窗口中。 當exe中的線程看到堆棧中的數據時,它也使用委托在主窗口中輸出數據。

我發現,如果我將代碼添加到DLL中的線程中,以便每30秒調用一次Application.DoEvents(),該接口將被凍結大約30秒,然后像平常一樣恢復活動。 我認為有什么東西阻塞了主線程並迫使DoEvents()觸發似乎打破了鎖,但是我不知道是什么原因導致了該鎖。

在我的開發計算機和測試計算機上均會發生此問題。

我嘗試將數據輸出完全刪除到DLL內的狀態窗口,但這沒什么區別。

我從事多線程編程已有多年了,從未見過這樣的事情。 因此,任何建議將不勝感激。

謝謝。

當您使用非標准方式初始化用戶界面時,這是SystemEvents類通常引起的問題。 特別是使用線程。 啟動程序,調試+全部破壞,調試+ Windows +線程。 如果您看到一個名為“ .NET SystemEvents”的線程,那么您肯定可以將其掛起。

背景知識:SystemEvent類同時支持控制台模式應用程序和GUI應用程序。 對於后者,它應該在UI線程上觸發其事件處理程序。 第一次訂閱其事件之一時,它會創建一個不可見的幫助程序窗口以獲取系統通知。 它可以通過在調用線程上創建窗口或啟動幫助程序線程來完成這兩種方式。 它基於Thread.GetApartmentState()的值進行決策。 如果它是STA,則可以在調用線程上創建窗口,並且所有事件回調都可以正確編組到該線程。

如果未在UI線程上創建您創建的第一個窗口,則會出錯。 例如啟動畫面。 該窗口可能包含對系統事件感興趣的控件,例如UserPreferenceChanged,以便它們可以正確地重新繪制自己。 現在,它使用助手線程,並且將從該助手線程而不是UI線程觸發任何事件。 毒害在UI線程上運行的任何窗口。 出於某種神秘的原因,從鎖定的工作站(包括屏幕保護程序)中退出會話很可能導致死鎖。 您可能還會看到偶爾的繪畫事故,這是使用錯誤線程中的窗口的較不愉快的結果。

除了確定初始化順序之外,一種變通方法是在創建任何窗口之前將其放入您的Main()方法中:

Microsoft.Win32.SystemEvents.UserPreferenceChanged += delegate { };

該問題確實與ActiveX控件有關,該ActiveX控件可能是在表格中使用不正確。 我改用.NET中的串行端口庫,但無法重現我的問題。 感謝所有人,尤其是漢斯的幫助。

我遇到了同樣的問題,因為屏幕保護程序啟動時我的PC只是掛起,或者我鎖定了PC並且顯示器進入睡眠狀態。 我95%確信多線程應用程序中出現死鎖。 查看並確定代碼中是否存在任何死鎖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM