等待任务.已完成任务是为了什么?



我使用在Build2017上引入的Windows Template Studio创建了UWP应用程序。

下面的类是从中生成的代码的一部分。

public class SampleModelService
{
public async Task<IEnumerable<SampleModel>> GetDataAsync()
{
await Task.CompletedTask; // <-- what is this for?
var data = new List<SampleModel>();
data.Add(new SampleModel
{
Title = "Lorem ipsum dolor sit 1",
Description = "Lorem ipsum dolor sit amet",
Symbol = Symbol.Globe
});
data.Add(new SampleModel
{
Title = "Lorem ipsum dolor sit 2",
Description = "Lorem ipsum dolor sit amet",
Symbol = Symbol.MusicInfo
});
return data;
}
}

我的问题是,在这里await Task.CompletedTask;代码的目的和原因是什么?它实际上没有Task结果接收器。

它的目的是使后期更容易实现异步代码调用,而无需更改签名,从而防止必须重构调用代码。

虽然基架示例代码是同步的,但模板工作室是专门围绕异步数据访问层设计的,您应该通过修改生成的方法的主体来实现自己的数据访问。

如果未实现异步实现,则整个模板化应用程序将发生重大代码更改,对于新开发人员来说,这将是一个非常陡峭的学习曲线,模板的重点是以最少的努力甚至经验启动并运行!

另一种选择是从方法签名中删除async关键字,该行并执行

return Task.FromResult<IEnumerable<SampleModel>>(data); 

当您需要返回可等待的任务时,例如,当实现没有异步工作要做时,您会看到此构造。

但是,在这种情况下,由于它是一个模板,他们希望人们用类似的东西替换await Task.Completedawait FetchDataFromDatabaseAsync();.由于async关键字已经存在,因此它最大限度地减少了实现您自己的异步调用所需的更改。

无论如何,如果没有这个等待结构,你可以这样做:

public class SampleModelService
{
public Task<IEnumerable<SampleModel>> GetDataAsync()
{
var data = new List<SampleModel>();
data.Add(new SampleModel
{
Title = "Lorem ipsum dolor sit 1",
Description = "Lorem ipsum dolor sit amet",
Symbol = Symbol.Globe
});
data.Add(new SampleModel
{
Title = "Lorem ipsum dolor sit 2",
Description = "Lorem ipsum dolor sit amet",
Symbol = Symbol.MusicInfo
});
return Task.FromResult<IEnumerable<SampleModel>>(data); 
}
}

如果根本不需要返回任务(您没有任何异步代码),则只需将其完全删除即可。(但是你必须重构调用此方法的代码)

回顾这段代码,我怀疑有人会在开发过程的后期调用异步方法,并且已经预料到通过指定此方法返回Task

await Task.CompleteTask使实现此方法更容易,因为第一个答案说,因为这个实现并不耗时,因此"等待 Task.CompleteTask;"或"返回 Task.FromResult(data);"两者将同步运行。您可以使用上面提到的这两种模式,但此方法设计为异步方法,因此,当您的实现很耗时但没有任何异步代码时,请使用Task.Run创建任务。

该方法声明为async。因此,编译器希望它await某些内容,例如对外部数据库的调用。

您的代码是同步的,因此编译器会警告您存在"代码异味"。您可以通过添加await Task.CompletedTask来禁止显示此警告 - 这不执行任何操作,但编译器会满意。

如果您有条件await,例如,当您检查方法参数或外部绑定尚未初始化时,这也很有用。

最新更新