본문 바로가기

c#

C# wpf Dispatcher DispatcherObjcet사용법 및 정의

 

WPF의 모든 UI관련 작업은 Main Thread가 수행합니다.

처음 시작할 때 있는 [STAThread]어트리뷰트가 위 내용에 해당 합니다.

여기서 STA 란 하나의 객체는 하나의 Thread에서만 엑세스할수 있도록하는 규칙과 제한입니다.

 

이때 WPF의 메인 Thread는 직접적으로 다른 Thread에 간섭을 받을수 없습니다.

즉 한 Thread에 생성된 컨트롤들은 그 Thread에서만 값을 변경 할 수 있습니다

해당 ui에 대한 쓰레드를 관리하는게 Dispatcher라는 큐 관리자이며

만약 해당 Dispatcher의 작업이 종료 되지 않았는데 ui를 변경하거나 조작하려 하면 에러가 발생하게 됩니다.

이를 방지하기 위해 사용하는것이 Dispatcher,DispatcherObject입니다.

 

DispatcherObject

WPF의 모든 UI관련 클래스는 dispatcherobject를 상속 받습니다.

//아래처럼  최종적으로는 dispatcherobject를 상속받음
TextBox - TextBoxBase - Control - FrameworkElement - UIElement - Visual - DependencyObject -DispatcherObject

-Method

CheckAccess

스레드가 해당객의 쓰레드에 엑세스하면 TRUE 아니면 FALSE이다.

 Button theButton = uiObject as Button;
 //스레드가 해당 객체의 쓰레드에 엑세스할수 있는지 여부를 리턴해줌
 theButton.CheckAccess();

VerifyAccess

현재 쓰레드와 생성할때의 쓰레드를 비교해 일치 하지않으면 THROW를 던진다.

//현재 쓰레드와 연관된 생성시에 저장된 쓰레드간 비교를 수행
 Button theButton = uiObject as Button;
theButton.VerifyAccess();

 

Dispatcher

 WPF의 어플리케이션 Thread마다 하나씩 생성됩니다.

-Thread생성 시 같이 생성되지 않고 Dispatcher를 처음 사용 하려 할 때 생성됨

-Method

Dispatcher는 아래 메서드들로 해당 Dispatcher가 있는 Thread에 작업을 요청합니다.

이때 요청한 작업을 work item이라고 칭하며 적절한 우선순위(System.Windows.Threading.DispatcherPriority)에

따라 실행 시킵니다.

invoke (동기식)

  //DispatcherPriority를 통해 우선순위를 지정하여 해당 메서드(work item)를 실행시킨다.
            Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => 
            {
            
            }));

단 invoke 메서드를 사용시에는 짧게 유지하는 것이 좋습니다 요청한 work item을 수행하느라 Thread를 잡고 있으면 그때 사용자가 UI를 조작하면 에러가 발생하기 때문입니다.

BeginInvoke(비동기식)

            //DispatcherPriority를 통해 우선순위를 지정하여 해당 메서드(work item)를 실행시킨다.
            Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => 
            {
            
            }));