我想知道是否有一些技術或方法來檢測WPF應用程序中不使用異步/等待的調用。有了WPF,有沒有一種方法可以檢測阻止GUI更新的方法調用?
我問的原因是我正在使用的WPF應用程序在屏幕更新上出現停頓和停頓,而且我似乎無法追蹤阻止GUI線程的調用源。
我正在使用VS2012和VS2013以及MVVM設計模式。
我想知道是否有一些技術或方法來檢測WPF應用程序中不使用異步/等待的調用。有了WPF,有沒有一種方法可以檢測阻止GUI更新的方法調用?
我問的原因是我正在使用的WPF應用程序在屏幕更新上出現停頓和停頓,而且我似乎無法追蹤阻止GUI線程的調用源。
我正在使用VS2012和VS2013以及MVVM設計模式。
這不會直接回答你的問題,但是這將有助於確定調度程序線程何時被重載,下面的代碼使用DispatcherInactive事件周圍的事件處理程序來計算調度程序線程在工作中被重載(阻塞)的時間:
var maxThreshold = TimeSpan.FromMilliseconds(750);
var previous = DateTime.Now;
Application.Current.MainWindow
.Dispatcher.Hooks.DispatcherInactive += (sender, eventArgs) =>
{
var current = DateTime.Now;
var delta = current - previous;
previous = current;
if (delta > maxThreshold)
{
Debug.WriteLine("UI Freeze = {0} ms", delta.TotalMilliseconds);
}
};
我建議,這是在調試模式下只使用過的,所以它會被包裹在一個#if DEBUG
塊。你不希望這個在生產中運行。
這段代碼絕對精彩。將它添加到代碼中,在「Debug」行上放置一個斷點,如果GUI線程被阻塞的時間過長,它會立即中斷。我希望我得到更多的回答。 – Contango 2014-09-12 09:51:59
高興地幫助... – AwkwardCoder 2014-09-12 13:15:16
你可以把它標記爲答案,並給我的觀點:) – AwkwardCoder 2014-09-12 13:15:52
我認爲performance profiler可以幫助你在這種情況下。 我個人推薦ANTS profiler,您可以下載試用版並使用它來測試您的應用程序。它會告訴你你的應用程序執行的某個時間段在哪裏花費時間。
通常很容易找到什麼阻止了UI。有可能在2案例 - 無論你是在UI線程上執行一個昂貴的操作,你可以測試是否在執行的線程使用UI線程:
if (Thread.CurrentThread == Dispatcher.CurrentDispatcher.Thread)
{
//UI Thread
}
或者,您顯示許多控件,它需要很長時間呈現。當列表不是虛擬化項目時,通常列表會導致此問題。
+1注意列表必須虛擬化項目。這對性能改進非常重要。 – Contango 2014-09-12 09:56:02
您可以訂閱WPF調度程序的事件來追蹤您的問題。 UI線程將隊列中的工作項目稱爲分派器。分派器優先選擇工作項目並運行每個項目以完成。
要監控分派器,您可以訂閱這些操作:
Dispatcher.Hooks.OperationPosted += Hooks_OperationPosted;
Dispatcher.Hooks.OperationStarted += Hooks_OperationStarted;
Dispatcher.Hooks.OperationAborted += Hooks_OperationAborted;
您找到完整的列表here。
根據您的問題,您可能會發現自己更擅長使用商業分析器,但通常只要觀察調度器隊列即可獲得良好的結果。
有關WPF調度程序線程如何工作的更多信息,請參閱http://weblogs.asp.net/pawanmishra/understanding-dispatcher-in-wpf。 – Contango 2014-09-12 10:04:38