'WPF'에 해당되는 글 1건

  1. 2008/09/11 [정리] WPF/Silverlight UI Threading 모델

애플리케이션이 구동되면서 화면 가득 정보를 채우고자 할 경우 백그라운드로 다수의 쓰레드를 만들어 서버와 통신하거나 연산 작업을 수행하는 일을 하게 되며, 일이 끝난 경우 이를 화면에 업데이트하는 것이 필요하다. 이 경우에 알아 두어야 할 것이 바로 UI 쓰레딩 모델이다. 대부분의 윈도우용 애플리케이션에서 UI 부분을 업데이트하는 쓰레드는 하나이며, 이는 WPF, Silverlight도 예외가 아니다.
한 애플리케이션 내에서 다수의 백그라운드 쓰레드를 생성하여 사용할 수 있으나, UI를 업데이트하는 쓰레드는 해당 UI 컴포넌트를 만들어낸 UI 쓰레드 하나다. 따라서 많은 쓰레드가 생성되어 백그라운드로 동시에 수행되어 업무 효율을 높일 수 있으나, 그 결과물을 화면에 반영하기 위해서는 UI 쓰레드에게 그 작업을 일임해야 한다. 백그라운드 쓰레드가 Dispatcher를 통해 UI 쓰레드에 작업을 할당하는 방법은 동기식으로는 Dispatcher.Invoke() 혹은 비동기 방식으로는 Dispatcher.BeginInvoke()를 통해서이다.

 
이러한 메소드의 호출을 통해서 전달된 작업들이 Dispatcher가 관리하는 큐에 쌓여 우선순위 (DispatcherPriority)에 근거하여 자신이 할당되어 있는 (즉, 연결된) 쓰레드를 통해 순서대로 실행하게 된다. 또한 Dispatcher는 자신이 연결되어 있는 쓰레드를 레퍼런스로 가지고 있으며, DispatherObject는 이러한 Dispatcher에 대한 레퍼런스를 가지고 있다. 이를 도식화하면, 아래 그림과 같다.

각각은 Association 관계로 엮여 있으며 DispacherObject를 통해 할당되어 있는 쓰레드에 이르기까지 접근이 가능하다. 맨 처음 코드에서 Button에 대해서 Dispatcher를 호출한 후 BeginInvoke()를 호출하여 작업을 일임하는 코드가 가능한 이유는, 아래 그림에서 보듯이 모든 UI 요소들이 바로 이 DispacherObject를 상속받아 만들어졌기 때문에, 상속에 의해 Dispatcher를 속성으로 가지게 되었기 때문이다.

쓰레드가 작업을 진행하면서 UI 요소를 업데이트하려할 때, 과연 이 쓰레드가 해당 UI에 접근 권한이 있는지를 점검하는 로직이 DispatcherObject에 CheckAccess()와 VerifyAccess()를 통해 제공되고 있다. DispatherObject (즉, UI 요소) 가 생성될 때 넘겨 받은 Dispatcher 객체와 접근하고 있는 쓰레드가 엮여 있는 Dispatcher 객체를 비교함으로써 쓰레드가 접근하고자 하는 DispatherObject (즉, UI 요소)에 업데이트 권한이 있는지를 검사하는 것이다.

Posted by 장현춘