this.Dispatcher.Invoke与SynchronizationContext

系统在MainWinow起来之后就给当前UI线程分配好了Dispatcher,这个Dispatcher属于MainWindow这个实例的,原因在于MainWindow继承自DispatcherObject类,而DispatcherObject包含了一个公共属性Dispatcher。实际上不仅仅是Window类,其他控件也都继承自DispatcherObject,因此他们在初始化时都自动赋值了Dispatcher属性,并且都指向同一个UI线程所拥有的Dispatcher对象。
同一个类下的方法根据你调用的方式不同,并不一定都运行于同一个线程下。即使调用其他类的函数,也可能存在两种情况,要么运行在一个线程里,要么运行在不同的线程里。实际上是否是一个线程里完全跟如何调度相关,跟是否属于哪个类没有任何关系。
多线程更新GUI-OnUIThread

主线程与子线程(或其他创建的多线程)通信 SynchronizationContext

var context = SynchronizationContext.Current;
context.Send(callback,null);
context.Post(callback,null);

Send 同步消息调度到一个同步上下文,send调用后会阻塞直到调用完成。
Post 异步消息调度到一个同步上下文,Post会启动一个线程来调用,不会阻塞当前线程。

callback可以处理与UI绑定的数据对象;

ContinueWith带来的延续任务continuation 不是从Task调用,是当前调度程序(TaskScheduler.Current)调度,一般是TaskScheduler.Default,一般TaskScheduler.Current是变化的。因此,continuation是在线程池(ThreadPool)中的一个线程上运行的,而线程池线程没有关联的同步上下文。所以延续任务与UI交互时,需要context的Post,此时Dispatcher无效。
或者可以在调用Task.Run以及Task.ContinueWith时始终显式指定任务计划程序,TaskScheduler.Default或TaskScheduler.FromCurrentSynchronizationContext()(必须在UI线程中调用)。