使用异步方法的结果
本文关键字:结果 异步方法 | 更新日期: 2023-09-27 17:54:34
我有一个简单的带有签名的异步方法:
public async Task<bool> AllowAccessAsync(string authenticatedUserToken)
调用此方法时,将其结果分配给局部变量时,我似乎有两个选项:
bool response = null;
// option 1
await this.transportService.AllowAccessAsync(authenticatedUserToken).ContinueWith(task => response = task.Result);
// option 2
response = await this.transportService.AllowAccessAsync(authenticatedUserToken);
第一个使用延续委托分配给局部变量,第二个将结果直接分配给变量。
这些有相同的结果吗?这两种方法有什么优点吗?有没有更好的方法可以做到这一点?
这些有相同的结果吗?
编辑:
@Servy正确地指出,因为ContinueWith
只是结果的投影。这意味着这两个操作在语义上是等效的,但在例外情况下,它们的行为会有所不同。
这两种方法有什么优点吗?有没有更好的方法可以做到这一点?
编辑 2:
下面的评论与async-await
与ContinueWith
的使用有关,一般来说。具体来看这两个示例,因为它们都使用 async-await
,一定要使用后者,因为两者都包含状态机生成,但后者会在发生异常时传播AggregateException
。
async-await
具有生成状态机的最小开销,而ContinueWith
则没有。另一方面,使用async-await
可以让您"感觉"同步,同时实际上是异步的,并为您节省了ContinueWith
冗长的时间。我肯定会选择async-await
,尽管我建议您研究使用它的正确途径,因为可能会有意想不到的可怜。
通过将async/await
与任务并行库的ContinueWith
一起使用,您会不必要地混合模式。 除非你别无选择,否则有很多理由不这样做,其中最重要的是async/await
的SynchronizationContext
没有被ContinueWith的默认实现所保留。
简而言之,选项 2 是正确的。
这些有相同的结果吗?
是的,这两个选项最终都会将相同的结果设置为 response
.唯一的区别发生在有异常时。在第一个选项中,引发的异常将是实际异常的AggregateException
包装器,而在第二个选项中,它将是实际异常。
这两种方法有什么优点吗?
以这种方式使用ContinueWith
绝对没有任何优势。第二个选项的优点是具有更好的异常处理,并且编写和读取更简单。
有没有更好的方法可以做到这一点?
不是真的,这就是你使用异步等待的方式。
正如Servy评论的那样,这不是ContinueWith
的使用方式。ContinueWith
等价物是将方法的其余部分放入延续中。所以取而代之的是:
public async Task FooAsync()
{
var response = await this.transportService.AllowAccessAsync(authenticatedUserToken);
Console.WriteLine(response);
}
你会这样做:
public Task FooAsync()
{
return this.transportService.AllowAccessAsync(authenticatedUserToken).
ContinueWith(task => Console.WriteLine(task.GetAwaiter().GetResult()));
}
这确实具有一些性能优势,因为它不需要异步等待状态机,但要正确处理非常复杂。
它更多地与编码风格有关。
当您有一个大型工作流,该工作流可能希望在执行承诺时分配不同的延续时,第一种样式可能很有用。但是,它依赖于闭包。我不建议使用这种用法,因为它并不总是可预测的。创建工作流时应使用该ContinueWith
,并且每个步骤仅依赖于前面的步骤,并且不与外部范围通信,除非交付产生最终结果的任务(然后您将等待该结果(。
当您只对结果感兴趣时,第二个很有用。
此外,ContinueWith
允许您指定一个TaskScheduler
,因为应用程序默认的那个可能不是您想要的。
有关TaskScheduler
的更多信息,请点击此处:http://blog.stephencleary.com/2015/01/a-tour-of-task-part-7-continuations.html