방프리
24.04.08 Chapter4. 병렬 처리 (Item 38) 본문
Item 38 : 스레드 간 커뮤니케이션에는 BackgroundWorker를 사용하라
BackgroundWorker는 ThreadPool을 이용하도록 만들어졌고 스레드 간 커뮤니케이션을 위한 여러 기능을 제공한다.
기존 QueueUserWorkItem의 단점
1. WaitCallback에서 발생하는 예외처리를 처리해야하는데 이 메서드가 예외를 던지면 전체 어플리케이션이 종료된다.
2. 백그라운드 스레드와 포그라운드 스레드 간 커뮤니케이션을 위한 기능을 전혀 제공하지 않는다. 만약 필요하다면 QueueUserWorkItem()의 기능을 활용해 만든 BackgroundWorker 컴포넌트를 사용
BackgroundWorker 사용방법
BackgroundWorker backgroundWorkerExample = new BackgroundWorker();
backgroundWorkerExample.DoWork += (sender, doWorkEventArgs) =>
{
// 작업 내용 생략
};
backgroundWorkerExample.RunWorkerAsync();
BackgroundWorker에서는 Foreground 스레드에서 요청을 보내면 BackgroundWorker가 Background 스레드 상에서 DoWork 이벤트를 발생시킨다. 그러면 DoWork 이벤트 핸들러가 주어진 매개변수를 읽어 작업을 시작한다.
Background 스레드가 작업을 끝내면 (DoWork 이벤트 핸들러에 정의된 대로 종료되면), Foreground 스레드에 RunWorkerCompleted 이벤트를 발생시키고 Foreground 스레드는 Background 스레드가 완료된 후의 후속 처리를 진행할 수 있다.
BackgroundWorker의 이벤트 중 WorkerSupportsCancellation 속성을 통해 Background 스레드가 연산을 중단하고 끝내는 사실을 알리기도 한다. WorkerReportsProgress는 작업 진행 상태를 정기적으로 Foreground 스레드에 보고한다. 또한 Foreground에서 작업 취소 요청이 있을 경우 이를 일리기도 하며 Background 스레드에서 CancellationPending 플래그를 통해 작업을 중단할 수도 있다.
또한 예외가 스레드 간 전달되지 못하는 문제점도 해결이 가능하다. BackgroundWorker에서 Background 스레드가 예외를 던지면 RunWorkerCompleted 이벤트의 매개변수인 RunWorkerCompletedEventArgs 인수의 Error 속성에 전달하여 문제를 해결한다. Background 스레드는 작업을 중단하고 Foreground 스레드는 RunWorkerCompleted 이벤트 핸들에서 예외를 처리한다.
BackgroundWorker는 여러 객체가 생성되더라도 모든 객체가 같은 스레드 풀을 공유하며 QueueUserWorkItem과 같이 여러 태스크가 수행될 수 있다. 대신 이벤트 핸들에서 Sender를 잘 확인해야 한다.
'C# > More Effective C#' 카테고리의 다른 글
24.04.20 Chapter4. 병렬 처리 (Item 40) (0) | 2024.04.20 |
---|---|
24.04.14 Chapter4. 병렬 처리 (Item 39) (1) | 2024.04.14 |
24.04.07 Chapter4. 병렬 처리 (Item 37) (0) | 2024.04.07 |
24.04.03 Chapter4. 병렬 처리 (Item 36) (0) | 2024.04.03 |
24.03.23 Chapter4. 병렬 처리 (Item 35) (1) | 2024.03.23 |