正确使用(或不使用)Dispatcher.CheckAccess()

时间:2012-10-17 15:32:43

标签: c# wpf

在Winforms中,所有控件都有一个InvokeRequired属性,如果必须调用则返回true。[Begin]调用控件以进行修改。

在WPF中,DispatcherObject.CheckAccess()Dispatcher.CheckAccess()中有一个明显相似的构造,但我被EditorBrowsable(EditorBrowsableState.Never)属性吓坏了。当我禁用这样的编辑器浏览时,我用它来表示“你应该这样做。不,真的。如果这是必要的,解决你的问题,你错误地设计了你的解决方案总体问题。“另一方面,我找到的唯一替代方案(事实上,我的原始解决方案)是Thread.CurrentThread.ManagedThreadId == 1。 (它太可怕了。它在通用情况下不起作用。我知道。但它确实适用于我的有限用途。)

MSDN documentationEditorBrowsable属性的存在和推理保持沉默。它是否确实意味着“不要使用它”,就像我输入它一样,或者它是否有其他一些不那么禁止的含义?

2 个答案:

答案 0 :(得分:15)

在WPF中,你可以调用Dispatcher.Invoke而不管你当前的线程,它会相应地处理调用 - 如果你已经在正确的线程上,它只会调用你的代码,它会使用它CheckAccess来处理此行为。

对于BeginInvoke您当前使用的线程无关紧要:BeginInvoke始终是异步的,执行顺序取决于您添加到调度程序队列的项目的优先级。< / p>

如果您根本不应该使用该方法,那么它将不公开:该属性的意图仅仅是隐藏成员与Intellisense和其他编辑器浏览器等机制。你通常不需要自己使用Dispatcher.CheckAccess(),这可能是为什么它被标记为不可浏览,但这是我们只能猜测的智慧(除非Eric Lippert正在观看; - )

总结:只需致电Dispatcher.Invoke,不要担心CheckAccess

答案 1 :(得分:0)

我想补充一下: 如果你想模仿&#34; If invokeRequired then ...&#34;
我会说:不要使用&#34; if Dispatcher.CheckAccess&#34; 相反,使用:

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