16

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

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

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

4

2 回答 2

23

在 WPF 中,Dispatcher.Invoke无论当前线程如何,您都可以调用,它会相应地处理调用 - 如果您已经在正确的线程上,它只会调用您的代码,并CheckAccess用于处理此行为。

对于BeginInvoke您当前所在的线程是无关紧要的:BeginInvoke始终是异步的,并且执行顺序取决于您添加到调度程序队列中的项目的优先级。

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

总结:只需打电话Dispatcher.Invoke,不用担心CheckAccess

于 2012-10-17T15:59:11.627 回答
0

我要补充一点:如果您想模仿“ 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
于 2013-01-21T18:33:29.567 回答