我似乎没有找到如何获得给定SynchronizationContext
的{{1}}:
Thread
为什么我需要它?
因为我需要从前端应用程序的不同位置发布到UIThread。所以我在名为Thread uiThread = UIConfiguration.UIThread;
SynchronizationContext context = uiThread.Huh?;
的类中定义了一个静态属性。我在UIConfiguration
方法中设置了这个属性:
Program.Main
在那一刻我可以肯定我有正确的线程,但是我不能设置像
这样的静态属性UIConfiguration.UIThread = Thread.CurrentThread;
因为尚未安装该类的WinForms实现。由于每个线程都有自己的SynchronizationContext,因此必须可以从给定的UIConfiguration.SynchronizationContext = SynchronizationContext.Current
对象中检索它,还是我完全错了?
答案 0 :(得分:12)
这是不可能的。问题是SynchronizationContext
和Thread
实际上是两个完全不同的概念。
虽然Windows Forms和WPF都为主线程设置了SynchronizationContext
,但大多数其他线程都没有。例如,ThreadPool中没有任何线程包含自己的SynchronizationContext(当然,除非你自己安装)。
SynchronizationContext
也可能与线程和线程完全无关。可以轻松设置同步上下文,以同步到外部服务或整个线程池等。
在您的情况下,我建议您在初始主表单的已加载事件中设置UIConfiguration.SynchronizationContext
。保证在此时开始上下文,并且在任何情况下消息泵启动之前都将无法使用。
答案 1 :(得分:7)
我知道这是一个老问题,并为死灵道歉,但我刚刚找到了解决这个问题的解决方案,我认为这对我们这些谷歌搜索过的人来说可能是有用的(并且它不需要控制实例)。
基本上,您可以创建WindowsFormsSynchronizationContext的实例,并在Main
函数中手动设置上下文,如下所示:
_UISyncContext = new WindowsFormsSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(_UISyncContext);
我已经在我的应用程序中完成了这项工作,它完美无缺。但是,我应该指出我的Main
标有STAThread,因此如果您的Main
标记为MTAThread,我不确定这是否仍然有用(或者如果有必要的话)。
_UISyncContext
已经在我的应用程序的Program
类的模块级别定义。
答案 2 :(得分:4)
我发现最简洁,最有帮助的是Alex Davies的书中的以下段落“Async in C#5.0.O'Reilly Publ。,2012”,p.48-49:
“SynchronizationContext is a class provided by the .NET Framework,能够在特定类型的主题中运行代码。
.NET使用了各种同步上下文,其中最重要的是WinForms和WPF使用的UI线程上下文。“
“SynchronizationContext
本身的实例没有做任何非常有用的事情,所以它的所有实际实例都是子类。
它还具有静态成员,可让您读取和控制当前SynchronizationContext
。
当前主题SynchronizationContext
是当前主题的属性。
这个想法是,在任何一个你在特殊线程中运行的时候,你应该能够得到当前的SynchronizationContext
并存储它。稍后,您可以使用它在您开始的特殊线程上运行代码。所有这一切都应该可以,而不需要确切知道你开始使用哪个线程,只要你可以使用SynchronizationContext,你就可以回到它。
SynchronizationContext的重要方法是Post
,它可以使代理在正确的上下文中运行“
。
“Some SynchronizationContexts encapsulate a single thread, like the UI thread。
有些封装一种特定类型的线程 - 例如,线程池 - 但可以选择中的任何一个将委托发布到。有些实际上并没有改变代码运行的线程,但仅用于监视,如ASP.NET同步上下文“
答案 3 :(得分:2)
我不相信每个 的帖子都有自己的SynchronizationContext
- 它只有一个线程本地SynchronizationContext
。
为什么不在表单的UIConfiguration.UIThread
事件中设置Loaded
或类似内容?