C#
C# UI Thread Crash 방지(InvokeRequired)
건실한청년
2022. 3. 8. 14:48
UI 스레드(Thread)
- UI 스레드
- UI만 처리하기 위한 스레드이며 모든 화면을 가진 프로그램은 공통적으로 있음(윈도우프로그램, 안드로이드 앱, 아이폰 앱 등)
- Work 스레드나 비동기 루틴 안에서 UI에 바로 접근 시에 UI Thread Crash가 발생하게 된다.
- Thread, async await 등
- 그래서 다른 스레드에서 UI에 접근 시에는 InvokeRequired를 사용하여 현재 진입한 스레드가 UI Thread인지 체크 한 후 UI 처리를 해야 문제가 없다.
예제 코드(1번, 2번 형식 중 편한것 사용하면 됨)
|
//스레드 에서 UI접근 |
|
public void ThreadFunc() { |
|
uiFunc(this.label1, "라벨", Color.lightGray); |
|
} |
|
new Thread(ThreadFunc).Start(); |
|
|
|
|
|
//1. delegate 사용 |
|
delegate void uiFunc_Callback(Label label, String text, Color backColor); |
|
void uiFunc(Label label, String text, Color backColor) |
|
{ |
|
//현재 스레드가 UI스레드가 아니면 delegate 이벤트로 전달 |
|
if (this.InvokeRequired) { |
|
uiFunc_Callback cb = new uiFunc_Callback(btnEnable); |
|
Object[] param = new Object[3]; |
|
param[0] = label; |
|
param[1] = text; |
|
param[2] = backColor; |
|
this.BeginInvoke(cb, param); |
|
} |
|
else { |
|
label.Text = text; |
|
label.BackColor = backColor; |
|
} |
|
} |
|
|
|
//2. EventHandler 사용 |
|
private void uiFunc(Label label, String text, Color backColor) { |
|
if(this.InvokeRequired) { |
|
this.Invoke(new EventHandler(delegate { |
|
label.Text = text; |
|
label.BackColor = backColor; |
|
})); |
|
} else { |
|
label.Text = text; |
|
label.BackColor = backColor; |
|
} |
|
} |