如何查找当前执行的代码是否在UI线程上?

时间:2011-04-13 10:32:25

标签: multithreading silverlight-4.0 autoresetevent

我正在开发一个silverlight应用程序,我有一个方法,如果它在UI线程上运行应抛出异常,因为它使用AutoResetEvent.WaitOne()而没有超时导致UI线程冻结。
如何检测当前线程是否是UI线程?

编辑:
请注意,此方法驻留在类库中,而不是UI组件中。

1 个答案:

答案 0 :(得分:1)

您可以使用Application.Current.Dispatcher检查您是否在主UI线程中(使用 CheckAccess()功能)。

注意我说主UI线程 - 这很重要,因为任何线程都可以有一个与之关联的调度程序*,并且你可以拥有多个UI线程。为了更准确,您的问题应该是

  

如何查找当前执行的代码 UI线程?

AFAIK这可能无法确定,因为后台(线程池)线程与UI线程之间唯一真正可辨别的差异(我已经看到)是他们的ApartmentState - UI线程是STA,并且线程可用在线程池中是MTA。这并不意味着STA线程是UI线程。 (我很高兴有人能在这里找到明确的东西)。也许您的解决方案是以另一种方式查看它 - 确保AutoResetEvent.WaitOne()调用仅在MTA的线程上完成。

*只是尝试在后台线程上执行代码this.Dispatcher.CheckAccess(),看看会发生什么......

修改

感谢@drow指出这应该是Silverlight ...呃。我将保持上面的答案不受影响,因为它仍然适用于WPF。正如@drow所提到的,无法访问Silverlight中线程的ApartmentState,并且使用 System.Threading.Thread.CurrentThread 时Dispatcher不可用。

因此,作为另一个选项,您可以检查Deployment.Current.Dispatcher.CheckAccess()是否返回 false ,如果是,那么您在后台线程(即不是主UI线程)。我做了测试,它运行得很好。