2012-10-17 5 views
10

Winforms에서 모든 컨트롤은 InvokeRequired 속성을 가지며 호출해야하는 경우 true를 반환합니다. [Begin] 컨트롤을 호출하여 수정합니다.Dispatcher.CheckAccess()의 올바른 사용법 (또는 사용하지 않음)

WPF의 경우 DispatcherObject.CheckAccess()Dispatcher.CheckAccess()에는 분명히 비슷한 구문이 있지만 나는 EditorBrowsable(EditorBrowsableState.Never) 속성으로 인해 두려워합니다. 이처럼 편집기 브라우징을 사용하지 않도록 설정하면 "이 아니라이되어야합니다."라는 메시지가 나타납니다. 문제가 해결되지 않으면 문제를 해결하기 위해 솔루션을 잘못 설계했습니다. " 반면에, 내가 찾은 유일한 대안은 (실제로, 원래의 솔루션) Thread.CurrentThread.ManagedThreadId == 1입니다. (끔찍합니다. 그리고 나는 알고있다. 그것은 일반적인 경우에 작동하지 않습니다. 그것은 내 제한된 용도로 작업을 수행하지만.)

MSDNdocumentationEditorBrowsable 속성 뒤의 존재와 추론에 침묵이다. 실제로 입력 한 경우와 같이 "사용하지 마십시오"는 의미입니까, 아니면 다른 덜 뜻깊은 의미가 있습니까?

+0

MSFT에서 몇 명이이 게시물에 답변 한 것으로 보입니다. http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/bd0e6f6c-cadd-48f1-8e1a-163c2f17e4ca/ 'EditorBrowsableState.Advanced'가 더 적절할 수도 있지만 보이지 않습니다. 왜 그 스레드에서 호출해서는 안되는 지에 대한 기술적 인 이유가 될 수 있습니다. – keyboardP

답변

15

WPF에서는 현재 스레드에 관계없이 Dispatcher.Invoke을 호출 할 수 있으며 그에 따라 호출을 처리합니다. 이미 올바른 스레드에 있으면 코드가 호출되고 을 처리합니다 이 행동.

BeginInvoke의 스레드는 현재 관련이 없습니다. BeginInvoke은 항상 비동기식이며 실행 순서는 발송자의 대기열에 추가하는 항목의 우선 순위에 따라 다릅니다.

이 메서드를 전혀 사용하지 않아야한다면 공개되지 않습니다.이 특성의 의도는 Intellisense 및 기타 편집기 브라우저와 같은 메커니즘에서 멤버를 숨기는 것입니다. 일반적으로 사용자가 Dispatcher.CheckAccess()을 사용할 필요는 없으므로 아마도이 항목은 탐색 할 수없는 것으로 표시되어 있지만,이 사실에 대한 지혜는 (에릭 리퍼트가보고 있지 않는 한) -

요약 할 수 있습니다. Dispatcher.Invoke으로 전화하면 CheckAccess에 대해 걱정할 필요가 없습니다.

+2

사용할 스레드를 결정하기 위해 스레드 액세스를 검사하는 것이 유리하다고 생각합니다. 명시 적 제어를 수행하거나 CheckAccess를 기반으로 특정 전제 조건을 수행하는 것이 경우에 따라 적절합니다. 그러나 그것의 버릇을 만드는 것은 나쁜 일입니다. 솔직히 말해서, Dispatcher.cs는 내가 본 중 가장 지독한 .NET 클래스 중 하나입니다. – erodewald

+0

유일한 단점은 UI를 업데이트 할 수있는 메소드를 기억하고 메소드를 호출 할 때 항상'Invoke()'를 사용하는 것을 기억해야한다는 것입니다. 메소드 안의 check/invoke와는 달리 걱정하지 않아도 항상 작동합니다. 그것에 대해 – Basic

+0

Dan 나는 올바른 스레드가 있다면 이미 코드를 호출하고 CheckAccess를 사용하여이 동작을 처리합니다. Dispatcher 클래스의 소스를 살펴보면 DispatcherPriority가 Send이면 CheckAccess 만 호출하는 것 같습니다. IMO, 단위 테스트에 유용한 Dispatcher 용 래퍼 클래스를 만드는 것이 좋습니다. 그러나 모든 Invoke 호출에 대해 CheckAccess를 매우 쉽게 추가 할 수 있습니다. 주 스레드에서 Dispatcher.Invoke를 호출하면 과거에 나에게 몇 가지 문제가 발생했습니다. – Zoman

0

내가 추가 할 : 을 당신이 해내하려면 "If invokeRequired then을 ..."
나는 말할 것입니다 : 내가 가진

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 


문제 "if Dispatcher.CheckAccess" 대신 사용을 사용하지 않는 의 checkAccess이 (가) ... 호출

신경 끄시을 시작 후에도 항상 사실이었다, 다음 코드는 잘 작동 :

If Me.Dispatcher.CheckAccess Then 
    Label1.Content = value 
    Else 
    Me.Dispatcher.BeginInvoke(New Action(Of String)(AddressOf displaymessage), value) 
    Return 
End If 
관련 문제