Using async/await with Dispatcher.BeginInvoke()

后端 未结 2 1112
时光说笑
时光说笑 2021-01-31 03:39

I have a method with some code that does an await operation:

public async Task DoSomething()
{
    var x = await ...;
}

I need tha

相关标签:
2条回答
  • 2021-01-31 04:24

    Use Dispatcher.Invoke()

    public async Task DoSomething()
    {
        App.Current.Dispatcher.Invoke(async () =>
        {
            var x = await ...;
        });
    }
    
    0 讨论(0)
  • 2021-01-31 04:39

    The other answer may have introduced an obscure bug. This code:

    public async Task DoSomething()
    {
        App.Current.Dispatcher.Invoke(async () =>
        {
            var x = await ...;
        });
    }
    

    uses the Dispatcher.Invoke(Action callback) override form of Dispatcher.Invoke, which accepts an async void lambda in this particular case. This may lead to quite unexpected behavior, as it usually happens with async void methods.

    You are probably looking for something like this:

    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
    }
    

    In this case, Dispatch.Invoke<Task<int>> accepts a Func<Task<int>> argument and returns the corresponding Task<int> which is awaitable. If you don't need to return anything from DoSomethingWithUIAsync, simply use Task instead of Task<int>.

    Alternatively, use one of Dispatcher.InvokeAsync methods.

    0 讨论(0)
提交回复
热议问题