我想知道是否有一些技术或方法来检测WPF应用中没有使用async / await的呼叫。
我问的原因是我正在处理的WPF应用程序在屏幕更新上是口吃和停顿,我似乎无法追踪阻止GUI线程的调用源。
我正在使用VS2012和VS2013以及MVVM设计模式。
答案 0 :(得分:6)
这不会直接回答您的问题,但这有助于识别调度程序线程何时重载,以下代码使用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
块中。你不希望它在生产中运行。
答案 1 :(得分:1)
我认为在这种情况下performance profiler可以帮到你。 我个人推荐ANTS profiler,您可以下载试用版并使用它测试您的应用程序。它会告诉您应用程序执行的某段时间在哪里花费时间。
答案 2 :(得分:1)
通常很容易找到阻止UI的内容。可能有两种情况 - 您要么在UI线程上执行昂贵的操作,您可以测试执行的线程是否是使用的UI线程:
if (Thread.CurrentThread == Dispatcher.CurrentDispatcher.Thread)
{
//UI Thread
}
或者,您正在显示许多控件,渲染需要很长时间。通常,当列表没有虚拟化项目时,列表会导致这种情况。
答案 3 :(得分:1)
您可以订阅WPF调度程序的事件来跟踪您的问题。 UI线程将名为Dispatcher的对象内的工作项排队。 Dispatcher优先选择工作项并运行每个工作项完成。
要监控Dispatcher,您可以例如订阅这些操作:
Dispatcher.Hooks.OperationPosted += Hooks_OperationPosted;
Dispatcher.Hooks.OperationStarted += Hooks_OperationStarted;
Dispatcher.Hooks.OperationAborted += Hooks_OperationAborted;
您可以找到完整列表here。
根据您的问题,您可能会发现自己更适合使用商业分析器,但通常只需观察调度程序队列就可以获得良好的结果。