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?
CancellationTokenis a more probable candidate for this thanIProgress<T>. WithIProgress<T>, you often have a differentTat different levels (higher-levelasyncmethods combine the progress notifications of their lower-levelawaitcalls). WithCancellationToken, the same token is almost always passed down to the lower-levelasyncmethods (assuming they support cancellation).CancellationTokendoes 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-levelasyncmethods. 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
CancellationTokento follow the invocations ofasyncmethods, even if they change thread contexts. I mean, consider this: methodAcallsConfigureAwait(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
CallContextclass?), but as soon as you do it your performance tanks (the execution context migration code is highly optimized for the default scenario).