WPF(Windows Presentation Foundation)는 UI 스레드 모델을 기반으로 작동합니다. UI 요소는 항상 UI 스레드에서만 접근하고 수정해야 합니다. 이때 Dispatcher가 등장합니다.
Dispatcher는 WPF 애플리케이션의 특정 스레드에서 실행될 작업을 관리하는 역할을 합니다. 특히 UI 요소가 생성된 스레드에서만 그 UI 요소에 접근이 가능하도록 보장합니다.
Dispatcher의 Invoke 메서드는 동기적으로 UI 스레드에서 작업을 수행합니다.
// 동기 호출 예제
Dispatcher.Invoke(() =>
{
labelStatus.Content = "작업 완료";
});
비동기적으로 UI 스레드에 작업을 예약할 때 사용합니다.
// 비동기 호출 예제
Dispatcher.BeginInvoke(new Action(() =>
{
labelStatus.Content = "비동기 작업 진행 중";
}));
비동기적으로 UI 스레드에 작업을 예약하고, Task를 통해 작업의 완료를 추적할 수 있습니다.
// InvokeAsync 호출 예제
await Dispatcher.InvokeAsync(() =>
{
labelStatus.Content = "InvokeAsync 작업 진행 중";
});
BeginInvoke: 작업을 예약하지만, 반환되는 DispatcherOperation을 통해 작업 상태를 확인하거나 대기할 수 있습니다. async/await 문법과 함께 사용되지 않습니다.InvokeAsync: 작업을 예약하고 Task를 반환하여 async/await 구문과 함께 작업 완료를 쉽게 추적할 수 있습니다.작업의 우선순위를 지정할 수 있습니다.
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
// 낮은 우선순위로 실행될 작업
}));
우선순위 종류:
DispatcherPriority.Normal: 일반 작업 (기본값)DispatcherPriority.Render: 렌더링 직전에 수행할 작업DispatcherPriority.Background: 배경 작업 (우선순위가 낮음)다음은 별도의 스레드에서 작업을 수행하고 Dispatcher를 통해 UI에 결과를 반영하는 예제입니다.
Task.Run(() =>
{
// 별도의 스레드에서 긴 작업 수행
var result = LongRunningOperation();
// 결과를 UI에 반영 (Dispatcher 사용)
Dispatcher.Invoke(() =>
{
txtResult.Text = result;
});
});
Dispatcher.Invoke는 동기적이므로 장기 실행 작업을 직접 호출하면 UI가 멈출 수 있습니다.Dispatcher를 사용할 때는 항상 예외 처리에 주의해야 합니다.
Dispatcher.BeginInvoke(new Action(() =>
{
try
{
// UI 업데이트 로직
}
catch (Exception ex)
{
// 예외 처리 로직
}
}));
Dispatcher 자체는 작업을 예약하는 것이므로, 내부적으로 발생한 예외는 Dispatcher의 바깥으로 전파되지 않을 수 있습니다.
Dispatcher는 WPF 애플리케이션에서 UI 스레드를 안전하게 관리하고 효율적으로 UI를 갱신하기 위한 핵심 도구입니다. Dispatcher를 올바르게 이해하고 사용하면 더욱 안정적이고 빠른 애플리케이션을 개발할 수 있습니다.