我正在开发一个 silverlight 应用程序,如果它在 UI 线程上运行,我有一个方法应该抛出异常,因为它使用 AutoResetEvent.WaitOne() 而没有超时,这会导致 UI 线程冻结。
如何检测当前线程是否为 UI 线程?
编辑:
请注意,此方法驻留在类库中,而不是 UI 组件中。
我正在开发一个 silverlight 应用程序,如果它在 UI 线程上运行,我有一个方法应该抛出异常,因为它使用 AutoResetEvent.WaitOne() 而没有超时,这会导致 UI 线程冻结。
如何检测当前线程是否为 UI 线程?
编辑:
请注意,此方法驻留在类库中,而不是 UI 组件中。
Application.Current.Dispatcher
您可以使用(使用CheckAccess()函数)检查您是否在主 UI 线程中。
注意我说的是主 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 线程)。我确实对此进行了测试,并且效果很好。