C# 에서 비동기로 개발이 필요한 순간
▶ 상황 요약
- UI에는 카운트를 계속 보여주는 TextBox가 있고
→ 이건 실시간으로 계속 업데이트되어야 합니다. - 사용자가 "저장" 버튼을 누르면 무거운 저장 작업을 해야 함
→ 이 작업은 오래 걸릴 수 있지만,
그 사이에도 UI(카운트 텍스트박스)는 계속 살아 있어야 함
🔸 동기(synchronous)로 저장하면?
private void btnSave_Click(object sender, EventArgs e)
{
SaveData(); // 저장 중에 UI 멈춤
}
✅ 문제: SaveData()가 무거운 작업이라면
❌ 그 동안 TextBox 업데이트가 멈추고, UI가 응답하지 않게 됩니다.
(버튼 클릭도 안 되고, 텍스트박스도 안 바뀜) 곤란곤란...
🔸 비동기(async)로 저장하면?
private async void btnSave_Click(object sender, EventArgs e)
{
await SaveDataAsync(); // 저장 중에도 UI는 멀쩡히 동작
}
이렇게 하면 UI 쓰레드는 그대로 살아있고,
SaveDataAsync()는 백그라운드에서 돌아가고,
TextBox는 계속 카운트가 올라갈 수 있답니다! (강력한 기능^^)
🔹 예시 코드 (카운트 + 저장 버튼)
int count = 0;
bool isRunning = true;
private void Form1_Load(object sender, EventArgs e)
{
Task.Run(async () =>
{
while (isRunning)
{
count++;
Invoke(new Action(() => txtCount.Text = count.ToString()));
await Task.Delay(1000); // 1초마다 증가
}
});
}
private async void btnSave_Click(object sender, EventArgs e)
{
btnSave.Enabled = false;
await SaveDataAsync(); // 비동기로 저장
btnSave.Enabled = true;
}
private async Task SaveDataAsync()
{
// 무거운 작업 시뮬레이션 (예: 파일 저장, DB 처리)
await Task.Delay(5000); // 5초 걸리는 저장
// 실제 저장 코드 여기에
}
☞ 이 구조 덕분에 텍스트박스는 실시간 카운트업 유지하고
무거운 저장은 자연스럽게 비동기 처리됩니다.
이런 구조가 바로 "UI는 유연하게 유지하면서,
백그라운드에서 무거운 작업을 하는" 모범 케이스입니다.
🔹 Invoke()가 필요한 이유
WinForms나 WPF처럼 UI 요소는 "UI 스레드"에서만 접근 가능합니다.
즉, 다른 스레드(예: Task.Run, Thread, Timer)에서
UI 컨트롤(txtCount 같은 텍스트박스 등) 을 직접 수정하면 오류가 납니다.
txtCount.Text = "100"; // ← 이 코드가 UI 스레드가 아닌 곳에서 실행되면 예외 발생!
🔸 그래서 Invoke()가 필요하답니다.
Invoke()는 UI 스레드에게 "이 코드 좀 대신 실행해줘!" 하고 부탁하는 거죠~
this.Invoke(new Action(() => {
txtCount.Text = count.ToString();
}));
이렇게 하면, 현재 코드가 UI 스레드가 아니라도
안전하게 txtCount.Text를 바꿀 수 있습니다.
🔹 정리해 보면
UI 스레드 | 화면을 그리는 주 스레드 (폼, 버튼, 텍스트박스 등을 관리) |
작업 스레드 | Task, Thread 등 백그라운드에서 일하는 스레드 |
Invoke() | UI 스레드에게 "이 코드는 네가 실행해줘!"라고 요청하는 방법 |
🔸 예시 (왜 Invoke()가 필요한지)
Task.Run(() =>
{
// 백그라운드에서 동작 중
txtCount.Text = "100"; // ❌ 예외 발생 (UI 스레드 아님)
this.Invoke(new Action(() =>
{
txtCount.Text = "100"; // ✅ UI 스레드가 대신 실행
}));
});
🔸 Invoke() vs BeginInvoke() 차이
Invoke() | UI 스레드가 끝날 때까지 기다림 (동기) |
BeginInvoke() | 바로 다음 코드로 넘어감 (비동기) |
C#의 비동기 프로그래밍은 초보자에게 약간 헷갈릴 수 있지만,
한 번 이해하고 나면 정말 강력한 도구가 될 수 있습니다.^^
'IT' 카테고리의 다른 글
MSSQL 숫자에서 문자, 문자에서 숫자 FORMAT CAST(... AS FLOAT) (0) | 2025.04.08 |
---|---|
C# Queue 사용법 예제 (0) | 2025.04.02 |
C# SWICH 문 예제 (0) | 2025.04.02 |
C# 델리게이트 이벤트핸들러 사용 예제 (0) | 2025.03.28 |
C# 델리게이트 이해 및 예제 (0) | 2025.03.28 |