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?
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).