如何等待覆盖异步函数
本文关键字:覆盖 异步 函数 等待 何等待 | 更新日期: 2023-09-27 18:15:40
我们有一个通用的Job
类,它有一个抽象的HeavyTask
方法,像这样:
abstract class Job {
private Task m_task;
protected abstract void HeavyTask();
public void StartJob(){
m_task = Task.Run(() => HeavyTask());
}
public async Task WaitJob(){
await m_task;
}
}
和派生类覆盖HeavyTask
函数,也使其异步:
class JobFoo : Job {
protected override async void HeavyTask()
{
await Task.Delay(1000);
Debug.WriteLine("JobFoo is done");
}
}
那么当我们使用这种方法时,似乎没有等待HeavyTask()
:
Job job = new JobFoo();
job.StartJob();
await job.WaitJob();
Debug.WriteLine("All Done");
输出:全部完成JobFoo is Done
如果我们没有覆盖HeavyTask
的async
,那么它是按预期工作的。但我不能保证那些推翻Job
的人不会把HeavyTask
变成async
。我想知道为什么它没有被成功地等待,是否有一种方法可以确保它被等待?如果可以,您是否还可以解释是否像上面所示的那样将非异步函数重写为async是一种好做法?
没有等待,因为没有可等待的(即Task
)等待。该方法的返回类型为void
。您应该避免在事件处理程序之外使用async void
。
如果你想让一个派生类使用async,让方法返回一个Task
开始:
protected abstract Task HeavyTaskAsync();
如果你需要有一个同步覆盖同步返回一个Task
:
override Task HeavyTaskAsync()
{
// do stuff;
return Task.CompletedTask;
}
我不认为这一行是可等待的:
m_task = Task.Run(() => HeavyTask());
配偶在等什么?无返回值
怎么样Task.Run(() => HeavyTask()).Wait();