Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance of Task.ContinueWith in non-async method vs. using async/await

Suppose you have a method that wraps an inner long-running method. This outer method may do a tiny amount of work before/after calling said long-running method. For example:

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

It seems like the added weight of the boilerplate code generated by using async is not necessarily worth the benefit of using await, since its continuation is basically trivial. Therefore, given a sufficiently trivial* continuation, is it more performant to use Task.ContinueWith? E.g.

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

* Yes, both 'sufficiently' and 'trivial' are vague terms. Also, I've ignored exception handling in this contrived example. I suppose the need to handle exceptions implies that the continuation is non-trivial.

like image 454
mztan Avatar asked Jan 28 '14 10:01

mztan


1 Answers

Therefore, given a sufficiently trivial* continuation, is it more performant to use Task.ContinueWith?

Yes, but I argue that this is the wrong question to ask.

It is more performant. However, you have to be very careful to handle edge cases (in particular, any exceptions raised by LongRunningAsync would get wrapped in an AggregateException by your code). In addition, await will capture a context by default, and resume the method in that context. You can handle special cases in a more performant way via ContinueWith, but you can't handle the general case in a more performant way.

But performance is the wrong question to ask anyway. I argue that a better question to ask is: Is the code sufficiently performant, and if so, which solution is more maintainable?

Consider how many times the code will be executed. Millions? How much time will be saved? A few nanoseconds? How much developer time with the ContinueWith approach cost? Every time anyone looks at the code, it takes that much longer to see what it's doing. It is a far, far better decision to save developer time by making the code more maintainable (concentrating the savings in your company) than it is to save an absolutely minuscule amount of time when the code is run (spreading the savings across all your clients - and spreading it so thin that no single client will even be aware of it).

like image 110
Stephen Cleary Avatar answered Oct 08 '22 03:10

Stephen Cleary