본문 바로가기
📁 [4] 개발자 정보 & 코드 노트/C#

C# Windows Forms 강의 106편: 멀티스레드 데이터 처리와 UI 갱신 (Task & ProgressBar 활용)

by wawManager 2025. 5. 21.

 

1. 강의 개요

이번 강의에서는 Task를 활용하여 비동기적으로 대량 데이터를 처리하면서 UI 응답성을 유지하는 방법을 학습합니다.
이전 강의(105편)에서는 BackgroundWorker를 사용했지만,
이번에는 Task 및 async/await을 활용하여 보다 현대적인 방식으로 구현합니다.

Task를 사용하면 UI와 별도로 작업을 수행하면서도 코드가 간결하고 유지보수가 쉬워집니다.
또한 ProgressBar를 연동하여 작업 진행률을 UI에서 실시간으로 표시하는 기능도 추가합니다.


2. 학습 목표

✅ Task 및 async/await을 활용한 멀티스레드 데이터 처리 구현
✅ UI가 멈추지 않도록 비동기 방식으로 데이터 처리
✅ ProgressBar를 통해 실시간 진행률 표시


3. 기능 요구사항

🟢 필수 기능

1️⃣ 백그라운드 데이터 처리 (Task 사용)

  • 무거운 연산(예: 100만 개 데이터 처리)을 백그라운드에서 실행

2️⃣ 진행률 표시 (ProgressBar 연동)

  • 작업이 진행됨에 따라 ProgressBar와 Label을 업데이트

3️⃣ UI 응답성 유지

  • 작업이 실행되는 동안에도 다른 UI 요소가 정상 작동

4. 실습: Task를 활용한 멀티스레드 데이터 처리

1️⃣ 폼 구성

  • 폼(Form) 이름: Form1
  • 컨트롤 배치:

컨트롤 타입 이름 위치 크기

Button btnStart 상단 (150 x 40)
ProgressBar progressBar 중앙 (300 x 30)
Label lblStatus 하단 (300 x 30)

📌 폼 디자인 예시:

------------------------------------------------
| [        btnStart (작업 시작)              ] |
| [  progressBar (작업 진행률 표시)         ] |
| [ lblStatus (현재 상태)                   ] |
------------------------------------------------

2️⃣ 코드 작성

(1) Task를 활용한 비동기 데이터 처리

using System;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp_TaskAsync
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // 버튼 클릭 시 비동기 작업 시작
        private async void btnStart_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = false; // 중복 실행 방지
            lblStatus.Text = "작업 시작...";
            progressBar.Value = 0;

            await ProcessDataAsync(); // 비동기 작업 실행

            lblStatus.Text = "작업 완료!";
            btnStart.Enabled = true;
        }

        // 비동기 작업 실행 (Task 활용)
        private async Task ProcessDataAsync()
        {
            int total = 100;

            for (int i = 1; i <= total; i++)
            {
                await Task.Delay(50); // 가상 작업 (50ms 딜레이)
                progressBar.Value = i;
                lblStatus.Text = $"진행률: {i}%";
            }
        }
    }
}

(2) Designer 코드

        private void InitializeComponent()
        {
            this.btnStart = new Button();
            this.progressBar = new ProgressBar();
            this.lblStatus = new Label();

            // 버튼 설정
            this.btnStart.Location = new System.Drawing.Point(10, 10);
            this.btnStart.Size = new System.Drawing.Size(150, 40);
            this.btnStart.Text = "작업 시작";
            this.btnStart.Click += new EventHandler(this.btnStart_Click);

            // ProgressBar 설정
            this.progressBar.Location = new System.Drawing.Point(10, 60);
            this.progressBar.Size = new System.Drawing.Size(300, 30);

            // Label 설정
            this.lblStatus.Location = new System.Drawing.Point(10, 100);
            this.lblStatus.Size = new System.Drawing.Size(300, 30);
            this.lblStatus.Text = "대기 중...";

            // Form 설정
            this.ClientSize = new System.Drawing.Size(330, 150);
            this.Controls.Add(this.btnStart);
            this.Controls.Add(this.progressBar);
            this.Controls.Add(this.lblStatus);
            this.Text = "Task를 활용한 멀티스레드 처리";
        }

3️⃣ 실행 결과

UI가 멈추지 않고 백그라운드에서 데이터 처리

  • "작업 시작" 버튼 클릭 → ProgressBar가 증가하며 UI가 정상적으로 작동

진행률이 실시간으로 표시됨

  • 작업이 진행되면서 Label과 ProgressBar가 업데이트됨

작업 완료 시 상태 메시지 변경

  • 100% 완료 시 "작업 완료!" 메시지 표시

5. 주요 개념 요약

  • Task 및 async/await 활용: 백그라운드에서 데이터 처리
  • await Task.Delay(50): UI를 멈추지 않고 일정 시간 대기
  • 비동기 UI 업데이트: ProgressBar 및 Label을 실시간 갱신
  • 버튼 활성화/비활성화: 작업 중에는 버튼을 비활성화하여 중복 실행 방지

📌 #CSharp #WindowsForms #멀티스레드 #Task #UI응답성유지