We have a generic Job
class which have an abstract HeavyTask
method like this:
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;
}
}
And the derived class override the HeavyTask
function and also make it async:
class JobFoo : Job {
protected override async void HeavyTask()
{
await Task.Delay(1000);
Debug.WriteLine("JobFoo is done");
}
}
Then when we are using this method, it seems that the HeavyTask()
is not awaited:
Job job = new JobFoo();
job.StartJob();
await job.WaitJob();
Debug.WriteLine("All Done");
Output:
All Done
JobFoo is Done
If we don't have async
for the override HeavyTask
, then it is working as expected. But I cannot guarantee those whose override the Job
won't make the HeavyTask
async
. I want to understand why it is not awaited successfully and is there a way to make sure it will awaited? If you can, could you also explain whether it is a good practice to override a non-async function as async as shown above?
It's not awaited because there's no awaitable (i.e. Task
) to await. That method has a void
return type. And you should avoid using async void
outside of event handlers.
If you want to enable a derived class to use async have the method return a Task
to begin with:
protected abstract Task HeavyTaskAsync();
And if you then need to have a synchronous override return a Task
synchronously:
override Task HeavyTaskAsync()
{
// do stuff;
return Task.CompletedTask;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With