调用异步方法应该使用Dispatcher.Invoke()吗?

huangapple go评论59阅读模式
英文:

Call async methods from Dispatcher.Invoke()?

问题

这种代码会带来问题吗(例如死锁),或者会按预期工作吗:

void CalledFromAnotherThread()
{
   Dispatcher.CurrentDispatcher.Invoke(DoUiStuff)
}

async Task DoUiStuff()
{
    await DoAsyncStuff();
}

当我根本不等待DoUiStuff时,是否应该将其改为返回void呢?

英文:

Can this kind of code bring trouble (e.g. deadlocks) or will it work as intended:

void CalledFromAnotherThread()
{
   Dispatcher.CurrentDispatcher.Invoke(DoUiStuff)
}

async Task DoUiStuff()
{
    await DoAsyncStuff();
}

When I am not awaiting DoUiStuff at all, should I make it return void then?

答案1

得分: 1

我会尽量避免调用 Dispatcher.Invoke。这会使前端和后端代码耦合在一起,导致代码更加复杂。我建议尝试将操作分解为在后台运行的部分,使用 await 等待它们,并在其中执行任何 UI 修改。

从注释中看,CalledFromAnotherThread 是一个回调。回调和事件可以使用 TaskCompletionSource 转换为任务,例如:

async Task DoSomethingAsync()
{
    var tcs = new TaskCompletionSource<bool>();

    _whatever.MyCallBack = ok =>
    {
        if (ok)
        {
            tcs.SetResult(true);
        }
        else
        {
            tcs.SetException(...一些内容...);
        }
    });

    _whatever.StartLongJob();
    return tcs.Task;
}

现在,您可以像对待其他异步调用一样异步等待 DoSomethingAsync

await DoSomethingAsync();
DoUiStuff();
await DoOtherAsyncStuff();
英文:

I'd try to avoid calling Dispatcher.Invoke altogether. This couples frontend and backend code and results in more complex code. I'd try to break the operations on parts that work on the background, await them with await and perform any UI modifications in between.

From the comments, it looks like CalledFromAnotherThread is a callback. Callbacks and events can be converted to tasks using TaskCompletionSource, eg :

async Task DoSomethingAsync()
{
    var tcs=new TaskCompletionSource&lt;bool&gt;();

    _whatever.MyCallBack= ok=&gt;{
        if(ok){
            tcs.SetResult(true);
        }
        else {
            tcs.SetException(...something...);
        }
    });
    _whatever.StartLongJob();
    return tcs.Task;
}

You can await DoSomethingAsync async now, like any other asynchronous call.

await DoSomethingAsync();
DoUiStuff();
await DoOtherAsyncStuff();

huangapple
  • 本文由 发表于 2023年2月23日 19:31:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75544229.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定