.net - Does the switching of a synchronization context mean that the work will run on the thread that owns the synchronization context? -


whether run task (and not task) so:

public async void button1_click(...) {     await task.run(...); } 

or using on of old methods call invokerequired check if there need invoke current operation on synchronization context, , call control.invoke (in case of winforms, example), operation performed using captured synchronization context, if there one.

however, of 2 things mean?

if request task run on thread pool thread using of methods, whether old or new, mean that:

  1. when thread gets off ground, switching of synchronization context means wait thread owns synchronization context execute piece of code? in case of ui owned sync context, mean thread pool thread post action message queue of ui thread , yield?

    or

  2. or mean thread pool thread execute action there switch of reference variable (system.threading.executioncontext.synchronizationcontext) holds synchronization context, , such, synchronization context co-operative discipline threads agree adhere to? work still done thread pool thread?

    of course, co-operative discipline*, not mean work alright if miscreant thread decided not switch synchronization context required. implication thread not owning synchronization context can still run if synchronizataion context reference changed right one.

from reading source code of asyncmethodbuilder<tresult>.start, system.threading.tasks.task.executewiththreadlocal , system.threading.executioncontext.runinternal method, seems highly answer #2, not sure.

update

here why assume #2 more love corrected.

if take windows forms application , stick button on , run code shown in picture in click event, might see call stack looks mine, shown in same picture.

enter image description here

i followed source code of each method in call stack. observed context switch happens in system.threading.executioncontext.runinternal method. happens because system.threading.tasks.executewiththreadlocal method passes value true last parameter of call system.threading.executioncontext.run method. please see line 2823.

however, thereafter, call proceeds without message posting ui thread's message queue , when reaches system.threading.tasks.task<tresult>.innerinvoke method, method invokes delegate.

if answer #1, if please show me message posting happens, i'll jump joy , have learnt fascinating synchronization context today.

does happen in executioncontext.setexecutioncontext method?

and if answer #2, , if confirm that, then, too, sing song in celebration of discovery.

side note

i made program test different, though. wanted see where synchronization context switched, if required, both:

  1. before await statement reached; and
  2. after await statement, i.e on continuation callback.

and findings have satisfactorily revealed me answers both questions.

for curious, switch made in asyncmethodbuilder's start method code before await expression.

for code after, there more 1 path. 1 of paths depicted in call stack shown in picture above.

i have async intro blog post explains how await works synchronizationcontext.current. specifically, await uses captured context resume async method.

so, not correct:

the operation performed using captured synchronization context, if there one.

if "the operation", mean ... in code:

public async void button1_click(...) {   await task.run(...); } 

what happen task.run schedule ... thread pool thread (task.run uses thread pool). await captures current synchronizationcontext (in case ui context) , returns. when ... completes, task returned task.run complete, , button1_click resume on context (the ui thread). reaches end of method , returns.

within ..., synchronizationcontext.current null. task continuation set await uses captured synchronizationcontext resume on ui thread.