C# WPF Dispatcher.InvokeAsync()具有异步委托的奇怪行为
如果您有一个异步方法,如下所示:C# WPF Dispatcher.InvokeAsync()具有异步委托的奇怪行为,c#,wpf,async-await,dispatcher,C#,Wpf,Async Await,Dispatcher,如果您有一个异步方法,如下所示: private async Task DoAsync() { Console.WriteLine(@"(1.1)"); Thread.Sleep(200); Console.WriteLine(@"(1.2)"); await Task.Delay(1000); Console.WriteLine(@"(1.3)"); } 您可以使用Dispatcher异步
private async Task DoAsync()
{
Console.WriteLine(@"(1.1)");
Thread.Sleep(200);
Console.WriteLine(@"(1.2)");
await Task.Delay(1000);
Console.WriteLine(@"(1.3)");
}
您可以使用Dispatcher异步调用它:
Console.WriteLine(@"(1)");
await Application.Current.Dispatcher.InvokeAsync(DoAsync);
Console.WriteLine(@"(2)");
您将获得以下输出:
(1)
(1.1)
(1.2)
(2)
(1.3)
如果使用Dispatcher.BeginInvoke()并等待事件完成,则效果相同(这是预期的):
控制台写入线(@“(1)”;
var dispatcherOp=Dispatcher.BeginInvoke(新函数(DoAsync));
dispatcherOp.Completed+=(s,args)=>
{
控制台写入线(@“(2)”;
};
我们在这里看到的是wait in DoAsync()方法使Dispatcher相信操作已结束
我的问题:这是一个bug还是一个特性?您知道任何描述这种行为的文档吗?我什么也找不到
我不是在要求解决方法。这是您的代码中的一个bug,从
Application.Current.Dispatcher.InvokeAsync(DoAsync)返回的对象
是一个任务
,您只等待外部任务,而不等待内部任务完成。这些情况就是我们的目的
您将得到的输出将是:(1)(1.1)(1.2)(1.3)(2)
“展开”所做的是有效地将代码转换为
Console.WriteLine(@"(1)");
await (await Application.Current.Dispatcher.InvokeAsync(DoAsync));
Console.WriteLine(@"(2)");
但是有一个好看的格式
有关文档,请参阅“”感谢您提供了非常有用的答案!:)我可以编写
InvokeAsync(DoAsync).Task.Unwrap()
,但不能编写InvokeAsync(DoAsync).Unwrap()
。我错过了什么吗?@oleh:Dispatcher.InvokeAsync返回一个DispatcherOperation,而不是任务,但是它是可等待的,因此wait关键字可以工作。获取任务并执行展开:Dispatcher.InvokeAsync(DoAsync.Task.unwrap()
Console.WriteLine(@"(1)");
await Application.Current.Dispatcher.InvokeAsync(DoAsync).Unwrap();
Console.WriteLine(@"(2)");
Console.WriteLine(@"(1)");
await (await Application.Current.Dispatcher.InvokeAsync(DoAsync));
Console.WriteLine(@"(2)");