英文:
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<bool>();
_whatever.MyCallBack= ok=>{
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();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论