然而,现在,如果问题出在异步方法中,这种方法不起作用 – 因为要执行的下一段代码被埋在延续任务中的某个地方(技术上它甚至没有挂起)…有没有办法这样做轻松调试任务?
UPD.
例:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private async void MainWindow_OnLoaded(object sender,RoutedEventArgs e) { await DoHolyWar(); MessageBox.Show("Holy war complete!"); } public static async Task DoHolyWar() { await DoHolyWarComplicatedDetails(); Console.WriteLine("Victory!"); } public static async Task DoHolyWarComplicatedDetails() { await BurnHeretics(); } public static Task BurnHeretics() { var tcs = new taskcompletionsource<object>(); // we should have done this,but we forgot // tcs.SetResult(null); return tcs.Task; } }
请注意,如果您启动它并点击“暂停”,您将只看到DoHolyWar方法挂起,但您不会看到确切的位置.如果你用’.Wait()替换’await’,并且做同样的事情,你将能够检查悬挂堆栈跟踪.使用此示例非常简单,但在实际应用程序中,通常很难找到问题.特别是桌面应用程序将在主线程上运行事件循环,因此即使某些内容“挂起”,并且您点击“暂停”,您也不会知道出现了什么问题.
解决方法
这可以为您提供有关挂起的任务的线索.
查找具有异常长持续时间值的任务,这表示任务发生了某些事情且未完成.如果双击该行,它将带您到等待挂起.
我不知道为什么要等待BurnHeretics();我没有在列表中显示,但我知道此窗口的行为会有所不同,具体取决于您的操作系统版本,因为它依赖于操作系统功能来跟踪某些类型的任务.但至少这会告诉你等待DoHolyWarComplicatedDetails();悬挂将导致您检查DoHolyWarComplicatedDetails(),它将引导您检查BurnHeretics();这将导致你导致挂起的bug.
更新:我刚刚意识到它确实显示等待BurnHeretics();作为主要的事情causnig块.如果查看Task列,< DoHolyWarComplicatedDetails> d__3表示“在DoHolyWarComplicatedDetails方法中,编译器生成的类< DoHolyWarComplicatedDetails> d__3已被调度,并且正在等待信号到达.” < DoHolyWarComplicatedDetails> d__3是等待BurnHeretics();的状态机,如果您使用像dotpeek这样的反编译器并允许显示编译器生成的代码,您可以看到它.
[CompilerGenerated] private sealed class <DoHolyWarComplicatedDetails>d__3 : IAsyncStateMachine { public int <>1__state; public AsyncTaskMethodBuilder <>t__builder; private TaskAwaiter <>u__1; public <DoHolyWarComplicatedDetails>d__3() { base..ctor(); } void IAsyncStateMachine.MoveNext() { int num1 = this.<>1__state; try { TaskAwaiter awaiter; int num2; if (num1 != 0) { awaiter = MainWindow.BurnHeretics().GetAwaiter(); if (!awaiter.IsCompleted) { this.<>1__state = num2 = 0; this.<>u__1 = awaiter; MainWindow.<DoHolyWarComplicatedDetails>d__3 stateMachine = this; this.<>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter,MainWindow.<DoHolyWarComplicatedDetails>d__3>(ref awaiter,ref stateMachine); return; } } else { awaiter = this.<>u__1; this.<>u__1 = new TaskAwaiter(); this.<>1__state = num2 = -1; } awaiter.GetResult(); awaiter = new TaskAwaiter(); Console.WriteLine("Heretics burned"); } catch (Exception ex) { this.<>1__state = -2; this.<>t__builder.SetException(ex); return; } this.<>1__state = -2; this.<>t__builder.SetResult(); } [DebuggerHidden] void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。