使用异步方法的结果

本文关键字:结果 异步方法 | 更新日期: 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-awaitContinueWith的使用有关,一般来说。具体来看这两个示例,因为它们都使用 async-await ,一定要使用后者,因为两者都包含状态机生成,但后者会在发生异常时传播AggregateException

async-await具有生成状态机的最小开销,而ContinueWith则没有。另一方面,使用async-await可以让您"感觉"同步,同时实际上是异步的,并为您节省了ContinueWith冗长的时间。我肯定会选择async-await,尽管我建议您研究使用它的正确途径,因为可能会有意想不到的可怜。

通过将async/await与任务并行库的ContinueWith一起使用,您会不必要地混合模式。 除非你别无选择,否则有很多理由不这样做,其中最重要的是async/awaitSynchronizationContext没有被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