wpf Dispatcher.CheckAccess() 的正确使用(或不使用)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12937902/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Correct usage (or not-usage) of Dispatcher.CheckAccess()
提问by DaleStan
In Winforms, all controls have an InvokeRequiredproperty, that returns true if I have to call .[Begin]Invoke on the control in order to modify it.
在 Winforms 中,所有控件都有一个InvokeRequired属性,如果我必须在控件上调用 .[Begin]Invoke 以修改它,则该属性返回 true。
In WPF, there is an apparently similar construct in DispatcherObject.CheckAccess()and Dispatcher.CheckAccess(), but I am frightened by the EditorBrowsable(EditorBrowsableState.Never)attribute. When I disable editor browsing like this, I use it to means "You should notbe doing this. No, really. If this is required solve your immediate problem, you have mis-designed your solution to your overarching problem." On the other hand, the only alternative I've found (and, in fact, my original solution) is Thread.CurrentThread.ManagedThreadId == 1. (It's horrible. And it doesn't work in the generic case. I know. It does work for my limited uses, though.)
在 WPF 中,DispatcherObject.CheckAccess()and 中有一个明显相似的构造Dispatcher.CheckAccess(),但我对这个EditorBrowsable(EditorBrowsableState.Never)属性感到害怕。当我像这样禁用编辑器浏览时,我用它来表示“您不应该这样做。不,真的。如果这需要解决您的紧迫问题,那么您就错误地设计了解决总体问题的解决方案。” 另一方面,我发现的唯一替代方案(实际上,我的原始解决方案)是Thread.CurrentThread.ManagedThreadId == 1. (这太可怕了。它在一般情况下不起作用。我知道。不过,它确实适用于我有限的用途。)
The MSDNdocumentationis silent on the presence of and reasoning behind the EditorBrowsableattribute. Does it indeed mean "do not use this", as it would if I had typed it, or does it have some other less prohibitive meaning?
在MSDN文档上的存在和推理背后沉默的EditorBrowsable属性。它确实意味着“不要使用这个”,就像我输入它一样,或者它是否有其他一些不那么令人望而却步的含义?
回答by Dan Puzey
In WPF, you can call Dispatcher.Invokeregardless of your current thread, and it'll handle the call accordingly - if you're already on the right thread, it'll just invoke your code, and it uses CheckAccessto handle this behaviour.
在 WPF 中,Dispatcher.Invoke无论当前线程如何,您都可以调用,它会相应地处理调用 - 如果您已经在正确的线程上,它只会调用您的代码,并CheckAccess用于处理此行为。
For a BeginInvokethe thread you're currently on is irrelevant: BeginInvokeis always asyncronous, and the order of execution is dependant on the priority of the item you add to the dispatcher's queue.
对于BeginInvoke您当前所在的线程是无关紧要的:BeginInvoke总是异步的,执行顺序取决于您添加到调度程序队列的项目的优先级。
If you weren't supposed to use the method at all, it wouldn't be public: the intent of that attribute is only to hide the member from mechanisms such as Intellisense and other editor-browsers. You don't typically need to use Dispatcher.CheckAccess()yourself, which is probably why it's marked as non-browsable, but the wisdom of this is something we can only guess at (unless Eric Lippert is watching ;-)
如果您根本不应该使用该方法,那么它就不会是公开的:该属性的目的只是将成员从 Intellisense 和其他编辑器浏览器等机制中隐藏起来。您通常不需要使用Dispatcher.CheckAccess()自己,这可能就是它被标记为不可浏览的原因,但是我们只能猜测它的智慧(除非 Eric Lippert 正在观看 ;-)
In summary: just call Dispatcher.Invokeand don't worry about CheckAccess.
总结:只要打电话Dispatcher.Invoke就行,不用担心CheckAccess。
回答by PatTheFrog
I would add:
if you want to mimick the "If invokeRequired then..."
I would say: do not use "if Dispatcher.CheckAccess"
Instead, use:
我要补充的是:如果你想模仿“ 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
The issue I had was that the CheckAccess was always true, even AFTER the begin invoke...
我遇到的问题是 CheckAccess 始终为真,即使在开始调用之后...
Nevermind, the following code also works fine:
没关系,以下代码也可以正常工作:
If Me.Dispatcher.CheckAccess Then
Label1.Content = value
Else
Me.Dispatcher.BeginInvoke(New Action(Of String)(AddressOf displaymessage), value)
Return
End If

