阅读短语"The current SynchronizationContext is a property of the current thread" correct"后,我有点困惑......
在VS2010的C#应用程序代码中,当我键入Thread.CurrentThread.
时,我没有在Intellisense给出的任何选项的下拉列表中找到线程的任何上下文相关属性。
我知道当前的同步上下文可以通过“= SynchronizationContext.Current;
”获得。但是,在并行线程,任务等中同时执行时,这并不是很幸运。
假设我从控制台或WPF (*)应用创建并启动a few Windows forms in its own main UI threads以及TPL任务。
我认为每个winform应该有自己的WindowsFormaSynchronizationContext,WPF应该有自己的DispatcherSynchronizationContext(SynchronizationContext class个子类)实例,任务在ThreadPool中执行凭借自己的同步上下文,LongRunning任务可以在其自己的同步上下文中从线程池中执行...
那么,为什么不能从线程中定义SynchronizationContext
?对"Get SynchronizationContext from a given Thread"问题的所有答案似乎都没有理由否定这种可能性......
最后,但并非最不重要:
短语"The current SynchronizationContext is a property of the current thread" correct"是否正确?
那么,如何为不同的特定线程实例获取此属性的值?
(*)
最近,我基本上使用winforms获得了C#WPF应用程序代码。
答案 0 :(得分:7)
这是准确的。 SynchronizationContext.Current属性使用当前线程的m_ExecutionContext字段。这是Thread类的私有字段,这就是您在IntelliSense下拉列表中看不到它的原因。
重要的是它以这种方式工作,默认的SynchronizationContext不会同步任何东西。它的Post()方法目标在线程池线程上运行。将目标调用编组到特定的线程是一项非常重要的事情。这需要目标线程的帮助,它需要为producer-consumer problem提供解决方案。通用解决方案是一个从线程安全队列中检索消息的循环。正是Winforms或WPF应用程序的UI线程的工作方式,它们“抽取消息循环”。 Application.Run()启动该循环。
因此,只有此类应用程序的UI线程才能支持不使用线程池线程运行Post()委托目标的同步提供程序。因此,Winforms和WPF会在您创建表单或窗口时立即安装自己的同步提供程序。并且只有在UI线程上运行的代码才能从SynchronizationContext.Current属性中看到非默认提供程序。
结果是您必须初始化需要将调用封送回UI线程上的UI线程的代码。因此,例如,必须在UI线程上创建BackgroundWorker。或者使用TaskScheduler.FromCurrentSynchronizationContext创建的任务。从技术上讲,可以有多个显示UI的线程,init代码运行的任何线程都决定了Post()委托目标的运行位置。这可能解释了您的问题,如果您的init代码在工作线程上运行,那么Post()目标在线程池线程上运行。只要您在UI线程上获得该引用,就可以将对Synchronization.Current对象的引用传递给工作线程。