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