High-level notes on the SynchronizationContext
DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT
Questions to Answer
- How do we safely do a fire-and-forget with async/await?
-
On what thread does the
SynchronizationContext
itself run? -
How do we access the
SynchronizationContext
? -
How does the
SynchronizationContext
differ from theIAsyncStateMachine
? -
What state does the
SynchronizationContext
capture?
Historical Context
ISynchronizeInvoke
standardizes use of the Windows Message Queue.
- queues work to a thread
- checks whether synchronization is necessary
- lets a source thread queue a delegate to a target thread
- if source is already target, does not bother queuing
- source can optionally wait for delegate completion
SynchronizationContext
replaces it to support ASP.NET async pages.
- queues work to a context (NOT to a thread)
- does NOT check whether synchronization is necessary
- maintains a count of outstanding operations
- every thread has an current context
SynchronizationContext
Implementations
WindowsFormsSynchronizationContext
&
DispatcherSynchronizationContext
- execute delegates on a single thread
- execute delegates one at a time
- execute delegates in queued order
Default
SynchronizationContext
- executes delegates on any thread from the process's thread pool
-
execute delegates one at a time -
execute delegates in queued order
AspNetSynchronizationContext
- execute delegates on any thread from the process's thread pool
- execute delegates one at a time
-
execute delegates in queued order - maintains the identity & culture of the initial thread
The Task Parallel Library (TPL)
-
uses
Task
objects as units of work -
executes tasks with the
TaskScheduler
-
the behavior of the default
TaskScheduler
... -
matches the behavior of the default
SynchronizationContext
- any thread
- any time
- any order
async/await
- in addition to creating a state machine ( de-compiled here ),
-
the
await
point captures the currentSynchronizationContext
- unless the current context is null
-
in which case it captures the current
TaskScheduler
-
ConfigureAwait(bool)
-
true
try to use the captured context to run the continuation -
false
not to use the captured context to run the continuation
-
Marshalling among Threads with Async/Await
- to marshal means "to transform data from one form to another"
-
in the context of threading, to marshal means
- to transform a unit of work, and
- to send it to another thread
-
await
asks for the currentSynchronizationContext
- then on continuation,
-
if the current context was null:
-
await
runs the operation in the originalTaskScheduler
-
-
else:
-
await
posts the operation to the captured context
-
-
the decision of where/when to run the operation belongs to the implementation of the
SynchronizationContext
andTaskScheduler
.
Schedulers
Give a scheduler some work and the scheduler determines:
- when to run that work
- where to run that work
Some schedulers:
- message pump (aka message loop, event loop, run loop)
-
System.Threading.ThreadPool
-
System.Threading.SynchronizationContext
-
System.Threading.Tasks.TaskScheduler
-
System.Reactive.Concurrency.EventLoopScheduler
-
System.Reactive.Concurrency.IScheduler
-
System.Windows.Threading.Dispatcher
SynchronizationContext
- is an abstract class that represents a scheduler
- has several virtual methods
-
e.g.
SynchronizationContext.Post()
- accepts a delegate and
- decides when/where to run it
TaskScheduler
-
uses the
ThreadPool
to queue and execute work -
the
ThreadPool
receivesTasks
as short-lived units of work
ThreadPool
-
maintains a global work queue
- it is FIFO
- it receives top-level tasks
- it de-queues work to the next available thread
-
maintains local work queues
- it is LIFO (i.e. like a stack)
- it receives nested tasks
- it is specific to the parent task's thread
White Elephant
-
an
ExecutionContext
contains a currentSynchronizationContext
-
the
SynchronizationContext
, among other things, determines the thread on which to run a delegate - delegate / unit of work / operation are vaguely synonymous
References
https://msdn.microsoft.com/magazine/gg598924.aspx
http://stackoverflow.com/questions/5600761/what-is-marshalling-what-is-happening-when-something-is-marshalled
https://blogs.msdn.microsoft.com/pfxteam/2012/01/20/await-synchronizationcontext-and-console-apps/
https://msdn.microsoft.com/library/system.threading.tasks.taskscheduler.aspx