等待Task.CompletedTask什么?

You*_*jae 15 c# task async-await uwp windows-10-universal

我使用在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Pet*_*ons 26

可能只是为了让以后的阶段更容易实现异步代码调用而不必更改签名,从而防止必须重构调用代码.

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

return Task.FromResult<IEnumerable<SampleModel>>(data); 
Run Code Online (Sandbox Code Playgroud)

当您需要返回由于接口而等待的任务时,您会看到此构造,例如,当实现没有异步工作时.

然而,在这种情况下,由于它是一个模板,他们希望人们await Task.Completed用类似的东西来代替await 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); 
     }
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 好吧,每当你"等待"某事时,你需要将`async`添加到方法签名中.有关为什么需要`async`关键字的更深入解释,请阅读以下文章:https://blogs.msdn.microsoft.com/ericlippert/2010/11/11/asynchrony-in-c-5-part-六往那 - 异步/.在这种特殊情况下,添加`async`关键字是合理的.由于这是一个模板,他们希望人们用`await FetchDataFromDatabaseAsync();来替换`await Task.Completed`. (4认同)