如何等待覆盖异步功能?
How to await for override async function?
我们有一个通用的 Job
class,它有一个像这样的抽象 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;
}
}
派生的 class 覆盖 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");
输出:
All Done
JobFoo is Done
如果我们没有 async
覆盖 HeavyTask
,那么它会按预期工作。但我不能保证那些覆盖 Job
的人不会成为 HeavyTask
async
。我想了解为什么没有成功等待它,有没有办法确保它会等待?如果可以的话,您能否也解释一下将非异步函数覆盖为异步函数是否是一种好习惯,如上所示?
没有等待,因为没有可等待的(即 Task
)等待。该方法具有 void
return 类型。并且您应该避免在事件处理程序之外使用 async void
。
如果要启用派生 class 以使用异步方法 return a Task
开头:
protected abstract Task HeavyTaskAsync();
如果您需要同步覆盖 return a Task
:
override Task HeavyTaskAsync()
{
// do stuff;
return Task.CompletedTask;
}
我认为这条线不可等待:
m_task = Task.Run(() => HeavyTask());
等待什么配偶?没有返回值。
怎么样
Task.Run(() => HeavyTask()).Wait();
我们有一个通用的 Job
class,它有一个像这样的抽象 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;
}
}
派生的 class 覆盖 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");
输出:
All Done
JobFoo is Done
如果我们没有 async
覆盖 HeavyTask
,那么它会按预期工作。但我不能保证那些覆盖 Job
的人不会成为 HeavyTask
async
。我想了解为什么没有成功等待它,有没有办法确保它会等待?如果可以的话,您能否也解释一下将非异步函数覆盖为异步函数是否是一种好习惯,如上所示?
没有等待,因为没有可等待的(即 Task
)等待。该方法具有 void
return 类型。并且您应该避免在事件处理程序之外使用 async void
。
如果要启用派生 class 以使用异步方法 return a Task
开头:
protected abstract Task HeavyTaskAsync();
如果您需要同步覆盖 return a Task
:
override Task HeavyTaskAsync()
{
// do stuff;
return Task.CompletedTask;
}
我认为这条线不可等待:
m_task = Task.Run(() => HeavyTask());
等待什么配偶?没有返回值。
怎么样
Task.Run(() => HeavyTask()).Wait();