不等待异步方法并立即评估IsCompleted时,会遇到什么情况?

时间:2019-04-01 14:33:05

标签: c# async-await

BackgroundService类包含以下代码:

public virtual Task StartAsync(CancellationToken cancellationToken)
{
    // Store the task we're executing
    _executingTask = ExecuteAsync(_stoppingCts.Token);

    // If the task is completed then return it, this will bubble cancellation and failure to the caller
    if (_executingTask.IsCompleted)
    {
        return _executingTask;
    }

    // Otherwise it's running
    return Task.CompletedTask;
}

我已读过https://www.markopapic.com/csharp-under-the-hood-async-await/,这使我假设ExecuteAsync直到其第一个(如果有的话)await ...的所有代码都在到达if (_executingTask.IsCompleted)之前执行。因此,如果ExecuteAsync的那部分发生任何异常,或者ExecuteAsync返回Task.CompletedTask,将导致执行return _executingTask;

我对此理解是否正确?

1 个答案:

答案 0 :(得分:2)

  

因此,如果ExecuteAsync的那部分发生任何异常,或者ExecuteAsync返回Task.CompletedTask,则将导致执行返回_executingTask;

通常,如果ExecuteAsync同步完成,则StartAsync返回从ExecuteAsync返回的任务。

在这种特殊情况下(具有后台服务),我认为它旨在处理先决条件检查之类的事情,这些检查通常在异步方法开始时同步进行。因此,如果后台服务同步确定它无法运行,那么StartAsync将返回错误的任务。

这种代码非常少见,并且设计令人怀疑。例如,如果后台服务异步确定无法运行,则不会发出任何通知。我认为,删除整个if (_executingTask.IsCompleted)块,或者将ExecuteAsync抽象更改为单独的InitializeAsyncExecuteAsync部分,行为会更加一致。