SynchronizationContext, when does it flow and when does it not?
asynchronous, c#, synchronizationcontext, task-parallel-library
Solution
Under what conditions will the current synchronization context flow with my async operations?
When an `async` method performs an `await`, by default it will capture a current context and use that to resume the `async` method. This context is `SynchronizationContext.Current` unless it is `null`, in which case it is `TaskScheduler.Current`. I describe this behavior in my `async` intro blog post, my MSDN article on `SynchronizationContext`, and my MSDN article on async best practices.
Are there differences between Task and others, e.g. Delegate.BeginInvoke?
This behavior is unique to `async` and `await`. `Delegate.BeginInvoke` means "run this delegate on a thread pool thread", so it doesn't propagate the `SynchronizationContext`. Neither do more modern approaches such as `Task.Run`.
If I execute stuff on the thread pool, am I forced to assign a synchronization context to that specific thread that is currently executing my work?
In general, you shouldn't install a synchronization context on a thread you don't own. If you do place one on a thread pool thread, it should be removed before the thread is returned to the thread pool. More likely, if you're installing a synchronization context, you just shouldn't ever give the thread back (a custom synchronization context is commonly associated with a "main loop" for that thread).
in the example above, logical call context flows but not synchronization context. any pointers to why this is the case would be interesting.
The other contexts are even less documented. Stephen Toub has the definitive post on the subject. In essence, some data such as security must flow; most other data does not.
Problem
I'm trying to learn about `SynchronizationContext` and friends. If I set a custom synchronization context at the start of e.g. a console app. Under what conditions will the current synchronization context flow with my async operations? Are there differences between `Task` and others, e.g. `Delegate.BeginInvoke` ? ``` void Main() { SynchronizationContext.SetSynchronizationContext(new FooContext()); Action a = () => { var current = SynchronizationContext.Current; //current is null here }; a.BeginInvoke(null,null); ...sleep ``` If I execute stuff on the thread pool, am I forced to assign a synchronization context to that specific thread that is currently executing my work?