🔎 유용한 정보
1. 강의 개요
이번 강의에서는 BackgroundWorker를 사용하여 긴 작업을 수행하는 동안 UI가 멈추지 않도록 비동기 작업을 처리하는 방법을 학습합니다.
이 강의에서는 파일 복사 시뮬레이션 예제를 통해 작업 진행률을 ProgressBar로 표시하며, 작업 완료 시 메시지를 표시하는 애플리케이션을 제작합니다.
2. 학습 목표
- BackgroundWorker의 기본 사용법 학습.
- 작업 진행률을 ProgressBar로 표시.
- 비동기 작업 완료 시 UI 업데이트.
3. BackgroundWorker란?
BackgroundWorker는 긴 작업을 비동기로 실행하면서, UI 스레드를 차단하지 않고 작업 상태를 업데이트할 수 있도록 설계된 컴포넌트입니다.
BackgroundWorker 주요 이벤트
이벤트 설명
DoWork | 백그라운드 작업 수행. |
ProgressChanged | 작업 진행률 변경 시 호출. |
RunWorkerCompleted | 작업 완료 시 호출. |
BackgroundWorker 주요 속성
속성 설명
WorkerReportsProgress | 진행률 보고를 활성화. |
WorkerSupportsCancellation | 작업 취소 지원 여부. |
4. 실습: 파일 복사 시뮬레이션
요구사항
- BackgroundWorker를 사용해 비동기 작업(파일 복사 시뮬레이션)을 구현.
- ProgressBar를 사용해 작업 진행률 표시.
- 버튼으로 작업 시작 및 취소.
폼 구성
컨트롤 타입 이름 텍스트 위치 크기
ProgressBar | progressBar1 | (없음) | 중앙 | (300 x 30) |
Button | btnStart | "작업 시작" | 하단 왼쪽 | (100 x 30) |
Button | btnCancel | "작업 취소" | 하단 오른쪽 | (100 x 30) |
코드 작성
Form1.cs
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private BackgroundWorker backgroundWorker;
public Form1()
{
InitializeComponent();
InitializeBackgroundWorker();
}
private void InitializeBackgroundWorker()
{
// BackgroundWorker 초기화
backgroundWorker = new BackgroundWorker
{
WorkerReportsProgress = true, // 진행률 보고 활성화
WorkerSupportsCancellation = true // 작업 취소 지원
};
// 이벤트 연결
backgroundWorker.DoWork += BackgroundWorker_DoWork;
backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
// 버튼 이벤트 연결
btnStart.Click += BtnStart_Click;
btnCancel.Click += BtnCancel_Click;
}
// "작업 시작" 버튼 클릭 이벤트
private void BtnStart_Click(object sender, EventArgs e)
{
if (!backgroundWorker.IsBusy)
{
progressBar1.Value = 0; // 진행률 초기화
backgroundWorker.RunWorkerAsync(); // 작업 시작
}
}
// "작업 취소" 버튼 클릭 이벤트
private void BtnCancel_Click(object sender, EventArgs e)
{
if (backgroundWorker.IsBusy)
{
backgroundWorker.CancelAsync(); // 작업 취소 요청
}
}
// BackgroundWorker DoWork 이벤트 (작업 실행)
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 100; i++)
{
if (backgroundWorker.CancellationPending) // 작업 취소 확인
{
e.Cancel = true; // 작업 취소 표시
return;
}
Thread.Sleep(50); // 작업 시뮬레이션 (0.05초 대기)
backgroundWorker.ReportProgress(i); // 진행률 보고
}
}
// BackgroundWorker ProgressChanged 이벤트 (진행률 업데이트)
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage; // ProgressBar 업데이트
}
// BackgroundWorker RunWorkerCompleted 이벤트 (작업 완료)
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
MessageBox.Show("작업이 취소되었습니다.", "알림");
}
else
{
MessageBox.Show("작업이 완료되었습니다!", "완료");
}
}
}
}
Form1.Designer.cs
namespace WindowsFormsApp1
{
partial class Form1
{
private System.ComponentModel.IContainer components = null;
private ProgressBar progressBar1;
private Button btnStart;
private Button btnCancel;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.progressBar1 = new ProgressBar();
this.btnStart = new Button();
this.btnCancel = new Button();
this.SuspendLayout();
// progressBar1
this.progressBar1.Location = new System.Drawing.Point(20, 20);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(300, 30);
this.progressBar1.TabIndex = 0;
// btnStart
this.btnStart.Location = new System.Drawing.Point(20, 70);
this.btnStart.Name = "btnStart";
this.btnStart.Size = new System.Drawing.Size(100, 30);
this.btnStart.Text = "작업 시작";
this.btnStart.UseVisualStyleBackColor = true;
// btnCancel
this.btnCancel.Location = new System.Drawing.Point(220, 70);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(100, 30);
this.btnCancel.Text = "작업 취소";
this.btnCancel.UseVisualStyleBackColor = true;
// Form1
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(350, 120);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnStart);
this.Controls.Add(this.progressBar1);
this.Name = "Form1";
this.Text = "비동기 작업 예제";
this.ResumeLayout(false);
}
}
}
5. 실행 결과
- 초기 상태
- ProgressBar는 비어 있고, "작업 시작"과 "작업 취소" 버튼이 표시됩니다.
- 작업 시작
- "작업 시작" 버튼 클릭 → ProgressBar가 점차 채워지고, 작업이 실행됩니다.
- 작업 중에도 UI는 응답성을 유지합니다.
- 작업 완료
- ProgressBar가 끝까지 채워지면 "작업이 완료되었습니다!" 메시지가 표시됩니다.
- 작업 취소
- "작업 취소" 버튼 클릭 → 작업이 중단되고 "작업이 취소되었습니다." 메시지가 표시됩니다.
6. 주요 개념 요약
- BackgroundWorker를 통한 비동기 작업
- 긴 작업을 UI 스레드와 분리해 실행하며, UI의 응답성을 유지.
- 작업 상태 업데이트
- ReportProgress와 ProgressChanged 이벤트를 사용해 작업 진행률 표시.
- 작업 취소 처리
- CancellationPending 속성을 확인해 작업 취소 로직 구현.
'📁 [4] 개발자 정보 & 코드 노트 > C#' 카테고리의 다른 글
C# Windows Forms 강의 48편: 리소스 관리 (이미지, 아이콘, 사운드 파일) (0) | 2025.03.23 |
---|---|
C# Windows Forms 강의 47편: 폼 간 데이터 전달 방법 (0) | 2025.03.22 |
C# Windows Forms 강의 45편: OpenFileDialog와 SaveFileDialog 고급 사용 (0) | 2025.03.20 |
C# Windows Forms 강의 44편: Timer와 GDI+를 활용한 간단한 애니메이션 효과 (0) | 2025.03.19 |
C# Windows Forms 강의 43편: Drag & Drop 기능 구현 (0) | 2025.03.18 |
🔎 유용한 정보