在Dispatcher.BeginInvoke()中使用async/await

Gig*_*igi 26 c# wpf lambda asynchronous async-await

我有一个方法,其中包含一些执行await操作的代码:

public async Task DoSomething()
{
    var x = await ...;
}
Run Code Online (Sandbox Code Playgroud)

我需要在Dispatcher线程上运行该代码.现在,Dispatcher.BeginInvoke()是等待的,但我无法将lambda标记为从内部async运行await,如下所示:

public async Task DoSomething()
{
    App.Current.Dispatcher.BeginInvoke(async () =>
        {
            var x = await ...;
        }
    );
}
Run Code Online (Sandbox Code Playgroud)

在内心async,我得到错误:

无法将lambda表达式转换为类型'System.Delegate',因为它不是委托类型.

我如何async从内部工作Dispatcher.BeginInvoke()

nos*_*tio 50

其他的答案可能引入了一个不起眼的错误.这段代码:

public async Task DoSomething()
{
    App.Current.Dispatcher.Invoke(async () =>
    {
        var x = await ...;
    });
}
Run Code Online (Sandbox Code Playgroud)

使用Dispatcher.Invoke(Action callback)覆盖形式Dispatcher.Invoke,async void在这种特殊情况下接受lambda.这可能会导致非常意外的行为,因为它通常会发生在async void方法中.

你可能正在寻找这样的东西:

public async Task<int> DoSomethingWithUIAsync()
{
    await Task.Delay(100);
    this.Title = "Hello!";
    return 42;
}

public async Task DoSomething()
{
    var x = await Application.Current.Dispatcher.Invoke<Task<int>>(
        DoSomethingWithUIAsync);
    Debug.Print(x.ToString()); // prints 42
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,Dispatch.Invoke<Task<int>>接受一个Func<Task<int>>参数并返回相应Task<int>的等待.如果您不需要返回任何内容DoSomethingWithUIAsync,只需使用Task而不是Task<int>.

或者,使用Dispatcher.InvokeAsync方法之一.

  • @ Cabuxa.Mapache:`Dispatcher.Invoke <任务<INT >>(()=> DoSomethingWithUIAsync(PARAM));` (4认同)