【问题标题】:How to await for override async function?如何等待覆盖异步功能?
【发布时间】:2015-10-03 04:08:52
【问题描述】:

我们有一个通用的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 已完成

如果我们没有 async 用于覆盖 HeavyTask,那么它会按预期工作。但我不能保证那些覆盖Job 的人不会创建HeavyTask async。我想了解为什么它没有成功等待,有没有办法确保它会等待?如果可以的话,您能否解释一下将非异步函数重写为 async 是否是一种好习惯,如上所示?

【问题讨论】:

  • 旧的异步无效问题。不要使用protected abstract void HeavyTask(); ,使用protected abstract Task HeavyTask();
  • 为什么你有单独的开始和等待方法?看起来你应该只有一个 StartJob 方法,它返回一个 Task 并让每个子类决定如何创建任务。
  • @EhsanSajjad 这不是 OP 询问的方法。
  • 您好@Lee,感谢您指出这一点。是的,你完全正确。这里不需要单独的WaitJob函数。

标签: c# .net asynchronous async-await task-parallel-library


【解决方案1】:

没有等待,因为没有可等待的(即Task)等待。该方法具有void 返回类型。您应该避免在事件处理程序之外使用async void

如果您想让派生类使用异步,请让方法返回 Task 开头:

 protected abstract Task HeavyTaskAsync();

如果您需要同步覆盖,则同步返回 Task

override Task HeavyTaskAsync()
{
    // do stuff;
    return Task.CompletedTask;
}

【讨论】:

    【解决方案2】:

    我不认为这条线是可以等待的:

    m_task = Task.Run(() => HeavyTask());
    

    配偶在等什么?没有返回值。

    怎么样

    Task.Run(() => HeavyTask()).Wait();
    

    【讨论】:

    • 你知道打电话给Task.Run(x).Wait()会发生什么吗?它将工作卸载到另一个线程,但线程被同步等待。因此,您需要一个线程执行HeavyTask 而不是一个线程执行HeavyTask,而一个线程等待它。
    • @Linky,你所说的甚至没有意义。我认为 wait() 仅指示线程在执行 I/O 操作时等待它完成工作,因此它是相同的步幅使其同步。
    • 并非如此。 Task.Run(() => HeavyTask()).Wait()Task task = Task.Run(() => HeavyTask()); task.Wait(); 几乎相同 Task task = Task.Run(() => HeavyTask()) 有什么作用?它将 HeavyTask() 卸载到另一个线程上。 task.Wait() 是做什么的?它同步等待一个任务。因此,您正在将 HeavyTask 卸载到另一个线程,但正在等待来自原始线程的另一个线程。这样做有什么好处?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2020-02-26
    • 1970-01-01
    • 2019-04-22
    • 2020-02-15
    相关资源
    最近更新 更多