C# 在已知已完成的任务上调用.Result或等待之间是否有区别?
以下代码块中是否存在任何功能、性能或死锁风险差异 例1: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; 以下代码块中是否存在任何功能、性能或死锁风险差异 不,没有这种情
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感谢您的评论。我将把它包括在我的答复中。