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)");