1월, 2023의 게시물 표시

WPF에서 Dispatcher가 필요한지 아닌지 확인하는 방법

 WPF에서 코딩을 하다 보면 수시로 마주하게 되는 Dispatcher  프로퍼티. System.Windows.Timer 를 사용하는 경우, Task 를 통해 비동기로 작업을 실행하는 경우 등등 비동기 프로그래밍을 하게 될 경우 UI 스레드에서 실행되어야 하는 메서드 호출을 위해 자주 사용되죠. (예: Close() , TextBlock.Text 수정, ... ) 예시 중 UI 엘리먼트의 프로퍼티 수정은 WPF의 강력한 Binding  기능으로 대체하면 되지만, 일정 시간 후 창이 닫히는 기능 등의 구현에는 XAML로 작성하는 것보다 간단하게 System.Windows.Timer 를 사용해 Elapsed  이벤트 발생 시 Close 를 호출하는 것이 간편합니다. 이런 상황에서, 그냥 Close 를 호출하면 크로스 스레드 문제가 발생하므로 Dispatcher를 사용해 UI 스레드에서 작업을 실행하게 되죠. 하지만 상황이 항상 이렇게 딱 정해져 있지는 않죠. 코딩을 하다가 보면 많은 경우를 마주하게 되고, Dispatcher를 호출해야 하는 상황인지 아닌지 확인해야 하는 상황 이 생기기도 합니다. 이 때 쓸 수 있는 것이 바로 Dispatcher.CheckAccess 메서드 입니다. private void CloseDialog() { DialogResult = false; // check if current context is ui context if (Dispatcher.CheckAccess()) Close(); else Dispatcher.Invoke(Close); } 위와 같이 Dispatcher.CheckAccess  메서드를 호출했을 때, 호출한 스레드가 해당 Dispatcher에 연결된 스레드이면 true 를, 아니라면 false 를 반환합니다. 따라서 true가 반환되었다면 그냥 UI 스레드 작업을 호출하면 되고, 아니라면 Dispatcher.Invoke  또는 Dispatcher.Be