Async CTP - Ambient CancellationToken and IProgress

742 views Asked by At

Bearing in mind the Async CTP promotes implicit scheduling via an ambient SynchronizationContext, is there any reason why I should not make my CancellationToken and IProgress ambient too?

I'm currently passing these through methods, much like I was passing a TaskScheduler around for explicit scheduling. However, seeing as the scheduler is now supposed to be ambient, mightn't I follow the same rule for the other pieces of the puzzle?

1

There are 1 answers

1
Stephen Cleary On BEST ANSWER

CancellationToken is a more probable candidate for this than IProgress<T>. With IProgress<T>, you often have a different T at different levels (higher-level async methods combine the progress notifications of their lower-level await calls). With CancellationToken, the same token is almost always passed down to the lower-level async methods (assuming they support cancellation). CancellationToken does support some really advanced combinators, but they're hardly ever used.

The primary disadvantage is that you'd be departing from the Task-based Asynchronous Pattern. You'd have to keep in mind that any Microsoft or 3rd-party code would take an explicit CancellationToken - sp you'd have to explicitly pull it out of your ambient context in your lowest-level async methods. Also, programmers maintaining your code base later are likely to expect TAP.

There's also a challenge when you consider implementation. You'd want the implicit CancellationToken to follow the invocations of async methods, even if they change thread contexts. I mean, consider this: method A calls ConfigureAwait(false) before awaiting the result of method B. You can't use a simple thread-local static property, because you need to follow the async execution context from one thread to another.

I seem to recall reading about a way to do this (possibly using the CallContext class?), but as soon as you do it your performance tanks (the execution context migration code is highly optimized for the default scenario).