首页 > 解决方案 > 当不等待异步方法并立即评估 IsCompleted 时,涵盖了哪些场景?

问题描述

该类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;

我对此的理解正确吗?

标签: c#async-await

解决方案


所以如果ExecuteAsync那部分出现异常,或者ExecuteAsync返回Task.CompletedTask,就会导致执行return _executingTask;

更一般地说,如果ExecuteAsync同步完成,则StartAsync返回从ExecuteAsync.

在这种特殊情况下(使用后台服务),我相信它旨在处理诸如前置条件检查之类的事情,这些事情通常在异步方法开始时同步完成。因此,如果一个后台服务同步确定它不能运行,那么StartAsync将返回一个故障任务。

这种代码极为罕见,设计也值得商榷。例如,如果后台服务异步确定它无法运行,则不会有任何通知。我认为删除整个块的行为会更加一致if (_executingTask.IsCompleted),或者将ExecuteAsync抽象更改为单独InitializeAsyncExecuteAsync部分。


推荐阅读