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

mzt*_*tan 5 .net c# task-parallel-library async-await

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

public async Task<int> LongRunningWrapperAsync()
{
    int result = await LongRunningAsync();
    result++;
    return result;
}
Run Code Online (Sandbox Code Playgroud)

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

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

*是的,'足够'和'琐碎'都是模糊的术语.此外,我在这个人为的例子中忽略了异常处理.我认为处理异常的必要性意味着延续是非平凡的.

Ste*_*ary 7

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

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

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

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

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