【问题标题】:How can I find out whether method executes on UI thread or not in a decoupled way?如何确定方法是否以解耦方式在 UI 线程上执行?
【发布时间】:2009-05-25 15:34:26
【问题描述】:

这是我遇到的问题:我需要确保在 UI 线程上实例化了一个对象。如果不是,它应该抛出异常。但是如何在方法内部检查它是否在 UI 线程上运行?注意:我不想将任何信息传递给对象的构造函数。

完美的候选者是 DispatcherSynchronizationContext(SynchronizationContext 的 WPF 实现),它在内部保存对 Dispatcher 的引用,该引用引用了与其关联的线程,但不幸的是,该字段是私有的,因此我无法访问它。

【问题讨论】:

    标签: c# .net wpf ui-thread


    【解决方案1】:

    小澄清,虽然通常只有 1 个 UI 线程,但可以有很多 UI 线程。 WPF 和 WinForms 都是如此。

    我发现实现这一目标的最佳方法是使用 SynchronizationContext。 WPF 和 WinForms 都将在它们运行 UI 的任何线程上建立 SynchronizationContext。如果我没有绑定到任何特定的 UI 模型,这就是我使用的功能。

    public bool IsPossiblyUIThread() {
      return SynchronizationContext.Current != null;
    }
    

    请注意,这绝不是万无一失的。非 UI 组件可以建立 SynchronizationContext,这对于简单的工作线程将返回 true。因此,非权威名称。

    稍微更可靠的方法如下。但它需要你至少引用 WPF 的一部分来实现。

    public bool IsLikelyWpfUIThread() {
      var context = SynchronizationContext.Current;
      return context != null && context is DispatcherSynchronizationContext;
    }
    

    【讨论】:

    • 是的,这似乎是最好的方法。非常感谢!
    【解决方案2】:

    Dispatcher.CheckAccess() 如果您的代码在与 Dispatcher 相同的线程上运行,则返回 true。如果只有一个 Dispatcher/UIThread,它应该可以工作。

    【讨论】:

    • 这可能是真的,但请注意,Dispatcher 始终与创建它的线程相关联。因此,如果对象是在另一个线程上创建的,则使用 Dispatcher.CheckAccess() 对您没有多大帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多