在Winforms中,所有控件都有 InvokeRequired
如果我必须调用,则返回true。[开始]调用控件以修改它。
在WPF中,有一个明显相似的结构 DispatcherObject.CheckAccess()
和 Dispatcher.CheckAccess()
,但我被吓坏了 EditorBrowsable(EditorBrowsableState.Never)
属性。当我禁用这样的编辑器浏览时,我用它来表示“你应该 不 这样做。不完全是。如果这是必要的,解决你的问题,你就错误地设计了解决你的首要问题的解决方案。“另一方面,我发现的唯一替代方案(事实上,我的原始解决方案)是 Thread.CurrentThread.ManagedThreadId == 1
。 (这太可怕了。它在通用情况下不起作用。我知道。但它确实适用于我的有限用途。)
该 MSDN 文件 对于背后的存在和推理保持沉默 EditorBrowsable
属性。它是否确实意味着“不要使用它”,如果我输入它,或者它是否有其他一些不那么禁止的含义?
在WPF中,您可以致电 Dispatcher.Invoke
无论你当前的线程如何,它都会相应地处理调用 - 如果你已经在正确的线程上,它只会调用你的代码,它会使用它 CheckAccess
处理这种行为。
为一个 BeginInvoke
你目前使用的主题是无关紧要的: BeginInvoke
始终是异步的,执行顺序取决于您添加到调度程序队列的项目的优先级。
如果您根本不应该使用该方法,那么它将不公开:该属性的意图仅在于将成员隐藏在诸如Intellisense和其他编辑器浏览器之类的机制中。您通常不需要使用 Dispatcher.CheckAccess()
你自己,这可能是为什么它被标记为不可浏览,但这是我们只能猜测的智慧(除非Eric Lippert正在观看;-)
总结:只需打电话 Dispatcher.Invoke
而且不用担心 CheckAccess
。
我想补充一下:
如果你想模仿“If invokeRequired then
......”
我会说:不要用“if Dispatcher.CheckAccess
“
相反,使用:
If Me.Dispatcher.Thread Is System.Threading.Thread.CurrentThread Then
Label1.Content = value
Else
Me.Dispatcher.BeginInvoke(New Action(Of String)(AddressOf displaymessage), value)
Return
End If
我遇到的问题是CheckAccess始终是真的,即使在开始调用之后......
没关系,以下代码也可以正常工作:
If Me.Dispatcher.CheckAccess Then
Label1.Content = value
Else
Me.Dispatcher.BeginInvoke(New Action(Of String)(AddressOf displaymessage), value)
Return
End If