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.BeginInvoke 등을 사용해 호출하면 됩니다.
댓글
댓글 쓰기