C# 在已知已完成的任务上调用.Result或等待之间是否有区别?

C# 在已知已完成的任务上调用.Result或等待之间是否有区别?,c#,async-await,task,C#,Async Await,Task,以下代码块中是否存在任何功能、性能或死锁风险差异 例1: await Task.WhenAll(task1, task2); var result1 = await task1; var result2 = await task2; 例2: await Task.WhenAll(task1, task2); var result1 = task1.Result; var result2 = task2.Result; 以下代码块中是否存在任何功能、性能或死锁风险差异 不,没有这种情

以下代码块中是否存在任何功能、性能或死锁风险差异

例1:

await Task.WhenAll(task1, task2); 
var result1 = await task1; 
var result2 = await task2; 
例2:

await Task.WhenAll(task1, task2); 
var result1 = task1.Result;
var result2 = task2.Result; 
以下代码块中是否存在任何功能、性能或死锁风险差异

不,没有这种情况

在这两种情况下,都会创建一个任务,该任务将在
task1
task2
完成时完成

因此,当你写作时:

var result1 = await task1; 
var result2 = await task2;
代码将同步执行。您不必等待,因为
task1
task2
都会完成

第二个例子也是如此,你试图得到他们的结果

var result1 = task1.Result;
var result2 = task2.Result; 
因为任务已经完成,所以您不会阻止任何调用线程的线程或任何上下文切换等

更新


这两种方法之间存在的唯一功能差异是错误处理不同。
等待
只会打开一个
聚合异常
,而
结果
只会引发异常。

查看结果会导致死锁。检查这个答案:@Cody-在这种情况下,我认为它不可能死锁,因为任务已经完成了。@JacodeGroot-Stephen对这个问题的回答非常详细,谢谢链接。在本例中,Task.WhenAll()可能已经打开了AggregateException的包装,所以这不是一个问题。这是功能上的差异,错误处理是不同的
wait
将打开
aggregateeexception
where
。Result
将完整地引发异常。@ScottChamberlain感谢您的评论。我将把它包括在我的答复中。