从给定的线程获取SynchronizationContext

时间:2010-11-05 15:41:35

标签: c# multithreading .net-3.5 synchronizationcontext

我似乎没有找到如何获得给定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 对象中检索它,还是我完全错了?

4 个答案:

答案 0 :(得分:12)

这是不可能的。问题是SynchronizationContextThread实际上是两个完全不同的概念。

虽然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或类似内容?