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

Multithreading 如何查找当前执行的代码是否在UI线程上?,multithreading,silverlight-4.0,autoresetevent,Multithreading,Silverlight 4.0,Autoresetevent,我正在开发一个silverlight应用程序,我有一个方法,如果它在UI线程上运行,应该抛出一个异常,因为它使用AutoResetEvent.WaitOne()而没有超时,这会导致UI线程冻结。 如何检测当前线程是否为UI线程 编辑: 请注意,此方法驻留在类库中,而不是UI组件中。您可以使用Application.Current.Dispatcher(使用CheckAccess()函数)检查是否位于主UI线程中 注意,我说的主UI线程-这很重要,因为任何线程都可以有一个与之关联的调度程序*,并且

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

编辑:

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

您可以使用
Application.Current.Dispatcher
(使用CheckAccess()函数)检查是否位于主UI线程中

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

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

好吧,这可能是不可能的,因为背景(线程池)线程和UI线程之间唯一可以辨别的区别(我已经看到)是它们的ApartmentState-UI线程是STA,线程池中可用的线程是MTA。但这并不意味着STA线程就是UI线程。(我很高兴有人能在这里插手一些确定的东西)。也许您的解决方案是从另一个角度看问题-确保只在MTA线程上执行
AutoResetEvent.WaitOne()
调用

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

编辑: 感谢@drow指出这应该是Silverlight。。。嗯。我将保持以上答案不变,因为它仍然适用于WPF。正如@drow所提到的,在Silverlight中无法访问线程的ApartmentState,并且在使用System.Threading.thread.CurrentThread时,调度程序不可用


因此,作为另一个选项,您可以检查
Deployment.Current.Dispatcher.CheckAccess()
是否返回false,如果返回false,则表示您处于后台线程(即不是主UI线程)。我做了测试,效果很好。

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

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

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

好吧,这可能是不可能的,因为背景(线程池)线程和UI线程之间唯一可以辨别的区别(我已经看到)是它们的ApartmentState-UI线程是STA,线程池中可用的线程是MTA。但这并不意味着STA线程就是UI线程。(我很高兴有人能在这里插手一些确定的东西)。也许您的解决方案是从另一个角度看问题-确保只在MTA线程上执行
AutoResetEvent.WaitOne()
调用

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

编辑: 感谢@drow指出这应该是Silverlight。。。嗯。我将保持以上答案不变,因为它仍然适用于WPF。正如@drow所提到的,在Silverlight中无法访问线程的ApartmentState,并且在使用System.Threading.thread.CurrentThread时,调度程序不可用


因此,作为另一个选项,您可以检查
Deployment.Current.Dispatcher.CheckAccess()
是否返回false,如果返回false,则表示您处于后台线程(即不是主UI线程)。我做了测试,效果很好。

@卓尔,谢谢你抓住了这个问题,我相应地编辑了我的答案。@卓尔,谢谢你抓住了这个问题,我相应地编辑了我的答案。