返回完成的任务的最佳方法是什么?

时间:2013-05-06 21:52:46

标签: c# .net task-parallel-library .net-4.5 c#-5.0

返回已完成的Task对象的最佳方法是什么?

可以写Task.Delay(0)Task.FromResult<bool>(true)无论如何。

但最有效的方法是什么?

3 个答案:

答案 0 :(得分:4)

Stephen Toub(MSFT)的回答:

  

如果您每次都想要一个新的Task对象,那么Task.FromResult是最多的   高效。 Task.Delay(0)在其当前实现中将返回一个   缓存任务,但这是一个实现细节。如果你想使用   一个缓存的任务,你应该自己缓存一个,例如私人静态   readonly Task s_completedTask = Task.FromResult(true);然后使用   s_completedTask。

答案 1 :(得分:4)

Task.FromResult将是最直接的。它还包括几个常见整数的内置结果等。但是,如果您的值不是“显而易见”的值(并且没有内置处理)但很可能经常在您的场景中返回 - 那么您可以创建自己的值缓存结果在一个字段中(如果合适,可能是静态的) - 但重要的是缓存Task,而不是结果本身.l - 否则每次只使用Task.FromResult。

答案 2 :(得分:3)

这里有一个小演示,展示了标记和未标记异步方法之间在异常处理方面的区别。

public Task<string> GetToken1WithoutAsync() => throw new Exception("Ex1!");

// Warning: This async method lacks 'await' operators and will run synchronously. Consider ...
public async Task<string> GetToken2WithAsync() => throw new Exception("Ex2!");  

public string GetToken3Throws() => throw new Exception("Ex3!");
public async Task<string> GetToken3WithAsync() => await Task.Run(GetToken3Throws);

public async Task<string> GetToken4WithAsync() { throw new Exception("Ex4!"); return await Task.FromResult("X");} 


public static async Task Main(string[] args)
{
    var p = new Program();

    try { var task1 = p.GetToken1WithoutAsync(); } 
    catch( Exception ) { Console.WriteLine("Throws before await.");};

    var task2 = p.GetToken2WithAsync(); // Does not throw;
    try { var token2 = await task2; } 
    catch( Exception ) { Console.WriteLine("Throws on await.");};

    var task3 = p.GetToken3WithAsync(); // Does not throw;
    try { var token3 = await task3; } 
    catch( Exception ) { Console.WriteLine("Throws on await.");};

    var task4 = p.GetToken4WithAsync(); // Does not throw;
    try { var token4 = await task4; } 
    catch( Exception ) { Console.WriteLine("Throws on await.");};
}
// .NETCoreApp,Version=v3.0
Throws before await.
Throws on await.
Throws on await.
Throws on await.

已从When async Task<T> required by interface, how to get return variable without compiler warning移动(并编辑))