Nic*_*sas 5 c# asynchronous task async-await
让我们看以下两个例子:
public class MyClass
{
public async Task Main()
{
var result1 = "";
var result2 = "";
var request1 = await DelayMe();
var request2 = await DelayMe();
result1 = request1;
result2 = request2;
}
private static async Task<String> DelayMe()
{
await Task.Delay(2000);
return "";
}
}
Run Code Online (Sandbox Code Playgroud)
和:
public class MyClass
{
public async Task Main()
{
var result1 = "";
var result2 = "";
var request1 = DelayMe();
var request2 = DelayMe();
result1 = await request1;
result2 = await request2;
}
private static async Task<String> DelayMe()
{
await Task.Delay(2000);
return "";
}
}
Run Code Online (Sandbox Code Playgroud)
在第一个示例中,您通常会如何编写async await
代码,其中一件事接一件事发生并正确等待。
第二个是首先调用该async Task
方法,但await
稍后调用。
第一个示例需要一些时间4000ms
来执行,因为await
它会在发出第二个请求之前计算第一个请求;但第二个例子需要一点2000ms
。发生这种情况是因为Task
一旦执行越过该var request1 = DelayMe();
行,实际上就开始运行,这意味着request1
并且request2
正在并行运行。在这一点上,await
关键字看起来只是确保Task
计算了 。
第二种方法的感觉和行为类似于await Task.WhenAll(request1, request2)
,但在这种情况下,如果 2 个请求中出现某些问题,您将立即收到异常,而不是等待所有内容计算完毕然后获得AggregateException
.
我的问题是,当一种方法的结果不依赖于另一种方法的执行时,使用第二种方法并行运行多个await
能力是否存在缺陷(性能或其他)Task
?查看降低的代码,看起来第二个示例生成了等量的System.Threading.Tasks.Task
1 per awaited item while the first one doesn't. Is this still going through the
async await` 状态机流?
如果两个请求中出现某些问题,您将立即收到异常,而不是等待所有内容计算完毕然后收到 AggregateException。
如果第一个请求失败,那么是的。如果第二个请求失败,那么不,在该任务完成之前您不会检查第二个请求结果await
。
我的问题是,当一个任务的结果不依赖于另一个任务的执行时,使用第二种方法并行运行多个可等待任务是否存在缺点(性能或其他方面)?查看降低的代码,看起来第二个示例生成了等量的 System.Threading.Tasks.Task1per 等待项,而第一个示例则没有。这是否仍在经历 async wait` 状态机流程?
它仍在经历状态机流程。我倾向于推荐,await Task.WhenAll
因为代码的意图更明确,但有些人不喜欢“即使有异常也总是等待”的行为。另一方面是Task.WhenAll
总是收集所有异常 - 如果您有快速失败行为,那么某些异常可能会被忽略。
关于性能,并发执行会更好,因为您可以同时执行多个操作。不存在线程池耗尽的危险,因为async
/await
不使用额外的线程。
作为旁注,我建议使用术语“异步并发”而不是“并行”,因为对许多人来说“并行”意味着并行处理,即Parallel
PLINQ,在这种情况下使用这将是错误的技术。
归档时间: |
|
查看次数: |
179 次 |
最近记录: |