Task.CompletedTask和Task.Result小记

在任何返回Task的方法中,如果可以在不进行异步的情况下计算结果,则最好避免使用Task.Run。
例如,一个简短的计算函数,或者测试中返回了一个预先计算过的结果,则无需使用Task.Run。
例如,定义了一个返回Task的接口方法,但是在实现中,并没有特别耗时的代码。

public interface IComputer    {    

    Task Do();

    Task<string> DoString();

}

一般我们会这样实现。即使实现中代码很简短。

public class Computer : IComputer { public Task Do() { return Task.Run(() => { //逻辑代码 }); } public Task<string> DoString() { return Task.Run( () => { //逻辑代码 return "aaa"; }); } }

实际上,Task类上面有两个帮助程序,,这些帮助程序让代码更具可读性,并且所需的运行时开销更少。

对于上述接口实现中的 Do方法,我更愿意使用 Task.CompletedTask。

public Task Do()    

    {            

        //逻辑代码

        return Task.CompletedTask;

    }

我们看一下CompletedTask的定义

/// Gets a task that has already completed successfully.

/// The successfully completed task.

public static Task CompletedTask { get; }

如果返回Task 怎么办?在这种情况下,如果您已经有了答案,请使用Task.FromResult包装答案。

public Task<string> DoString() 

{

    //逻辑代码

    return Task.FromResult("aaa");

}

看一下FromResult的定义

/// Creates a  that's completed successfully with the specified result.

/// The result to store into the completed task.

/// The type of the result returned by the task.

/// The successfully completed task.

public static Task FromResult<[Nullable(2)] TResult>(TResult result);

通过上述的改变,即实现了接口的实现,也减少了Task.Run调用的系统开销。

·END·


DotNetCore学习站

超乎想象的.NET Core学习资源


微信号:DotNetCore学习站