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 thanIProgress<T>
. WithIProgress<T>
, you often have a differentT
at different levels (higher-levelasync
methods combine the progress notifications of their lower-levelawait
calls). WithCancellationToken
, the same token is almost always passed down to the lower-levelasync
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-levelasync
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 ofasync
methods, even if they change thread contexts. I mean, consider this: methodA
callsConfigureAwait(false)
before awaiting the result of methodB
. 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).