Task.ContinueWith在非异步方法中的性能与使用async / await的性能

时间:2014-01-28 10:28:41

标签: c# .net task-parallel-library async-await

假设您有一个包装内部长时间运行方法的方法。这种外部方法可以在调用所述长时间运行的方法之前/之后进行少量工作。例如:

public async Task<int> LongRunningWrapperAsync()
{
    int result = await LongRunningAsync();
    result++;
    return result;
}

似乎使用async生成的样板代码的附加权重不一定值得使用await,因为它的延续基本上是微不足道的。因此,给定一个足够微不足道的*延续,使用Task.ContinueWith是否更高效? E.g。

public Task<int> LongRunningWrapperAsync()
{
    return LongRunningAsync().ContinueWith(task => task.Result + 1,
                 TaskContinuationOptions.ExecuteSynchronously);
}

* 是的,“充分”和“微不足道”都是模糊的术语。此外,我在这个人为的例子中忽略了异常处理。我认为处理异常的必要性意味着延续是非平凡的。

1 个答案:

答案 0 :(得分:6)

  

因此,给定一个足够微不足道的*延续,使用Task.ContinueWith是否更高效?

是的,但我认为这是一个错误的问题。

性能更高。但是,您必须非常小心处理边缘情况(特别是,LongRunningAsync引发的任何异常都会被代码包含在AggregateException中。此外,await将默认捕获上下文,并在该上下文中恢复该方法。您可以通过ContinueWith以更高效的方式处理特殊情况,但是您无法以更高效的方式处理一般情况。

但无论如何,表现是一个错误的问题。我认为更好的问题是:Is the code sufficiently performant, and if so, which solution is more maintainable?

考虑代码执行的次数。百万?会节省多少时间?几纳秒?使用ContinueWith方法花费多少开发人员时间?每次有人查看代码时,都需要花费更长的时间才能看到它正在做什么。通过使代码更易于维护(集中节省您的公司)而不是节省绝对微小的数量,节省开发人员时间是一个远远更好的决定代码运行的时间(将节省的资金分散到所有客户端 - 并将其分散到如此之小以至于没有任何一个客户端会意识到它)。