2010-11-02 129 views
2

這是一個問題的兩個部分:找到該模塊阻塞UI線程

  • 我在哪裏由不同的團隊開發了多個插件加載一個共同的容器殼內的大項目合作。有時我可以看到我的UI更新被阻塞,因爲有多個並行UI更新,我想知道是否有方法可以找到哪個組件阻塞UI線程

  • 在.net中如何創建單獨的UI線程需要專門的UI密集型工作?

非常感謝您的幫助。謝謝。

回答

1

Visual Studio 2010(更高的SKU)包含檢查此功能的功能。如果你在Concurrency Profiler下運行你的程序,你可以看到哪些線程正在等待發生死鎖時鎖定哪些鎖。此外,它將突出顯示僵局(我相信鮮紅色),以便於追蹤。

+0

我們該怎麼做? ty非常我真的需要找出哪些塊使其凍結ui線程 – MonsterMMORPG 2015-01-15 13:22:23

+0

@MonsterMMORPG在併發事件探查器下運行您的程序。它顯示了它何時被阻止,哪些線程和任務被阻止,以及他們在等待什麼。 – 2015-01-15 17:18:08

4

使用調試器。當你注意到它被阻塞時,Debug + Break All。然後調試+ Windows +線程並選擇主線程。調用堆棧窗口顯示它在做什麼。

轉角情況是這些插件使用大量Control.Begin/Invoke或Dispatcher.Begin/Invoke調用的情況。在這種情況下,您的UI線程不會被阻塞,它只是被分派委託目標的請求所淹沒。並且不再忙於履行其正常職責,例如重新繪製窗口並響應鼠標和鍵盤事件。除了與插件作者合作讓他們修補他們的方式之外,您無法做到這一點。

您已經有了一個UI線程,即創建第一個窗口的線程。創建具有自己窗口的其他線程是可能的,但會導致窗口Z順序無法解決的問題(窗口將在另一個應用程序的窗口下消失)以及窗口互操作線程痛苦的慷慨幫助。

+0

好吧,它並沒有顯示我所有的外部代碼,但仍然ui被凍結無響應或非常緩慢 – MonsterMMORPG 2015-01-15 13:22:56

1

你可以採取的一種方法(儘管它可能需要一點重新設計)是禁止在UI線程中運行所有插件邏輯。所有需要更新UI的操作都必須通過定義良好的服務接口進行路由,這些接口可以解釋,調度並甚至可以限制UI更新。如果你的插件不是以UI爲中心的,並且你有一個服務模型,它允許你將插件操縱的數據與該數據的可視化分離開來,這是唯一可行的。在不瞭解你的申請的情況下,我不能給出更具體的建議。

1

下面是我很快想到的問題的兩種可能的解決方案。我相信還有其他同樣有效的解決方案。代替使用推模式(經由ISynchronizeInvoke方法)切換到其中所述UI查詢更新插件上拉(或輪詢)模型的:

選項1。這具有以下優點。

  • 它打破了用戶界面和Control.Invoke強加的工作/插件線程之間的緊密耦合。
  • 它將UI線程更新的責任置於UI線程上,無論如何它應該屬於它。
  • UI線程可以決定更新應該發生的時間和頻率。
  • 不存在UI消息泵被超載的風險,就像工人/插件線程啓動的封送處理技術一樣。
  • 工作者/插件線程無需等待在執行其下一步(即在UI和worker/plugin線程上獲得更多吞吐量)之前執行更新的確認。

選項2:有插件接受ISynchronizeInvoke實例,而不是實際的FormControl的。這個特殊的同步對象將使用專用線程和充當插件和UI之間緩衝區的隊列來實現。它將通過正常的InvokeBeginInvoke方法來接受更新消息,這意味着您可以保持插件體系結構和接口大部分完好無損,然後在發生某種類型的過濾,合併和限制操作後將這些消息轉發到UI。存在於同步對象中的更新消息的數量將隨着UI和插件線程工作負載變化而逐漸消失和流動。隨着消息速度的增加,它可以足夠聰明地改變它的轉發策略。