如何以分离的方式找出方法是否在UI线程上执行?

时间:2009-05-25 15:34:27

标签: c# .net wpf ui-thread

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

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

2 个答案:

答案 0 :(得分:9)

虽然通常只有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;
}

答案 1 :(得分:2)

如果您的代码与Dispatcher在同一个Thread上运行,则

Dispatcher.CheckAccess()返回true。如果只有一个Dispatcher / UIThread,它应该可以工作。