C#에서 크로스 스레드 예외 방지: UI 컨트롤을 안전하게 업데이트
문제: C# 애플리케이션에서는 기본 UI 스레드가 아닌 스레드에서 UI 컨트롤을 업데이트할 때 "크로스 스레드 작업이 유효하지 않음" 예외가 자주 발생합니다. 이는 마이크로 컨트롤러의 UART 포트와 같은 외부 소스의 데이터를 별도의 스레드에서 처리할 때 일반적으로 발생합니다.
시나리오: 마이크로컨트롤러가 UART를 통해 온도 데이터를 전송한다고 상상해 보세요. C# 애플리케이션은 백그라운드 스레드에서 이 데이터를 수신하지만 온도 값으로 TextBox
을 직접 업데이트하려고 하면 예외가 발생합니다.
근본 원인: UI 컨트롤은 생성된 스레드에 바인딩됩니다. 다른 스레드에서 액세스하는 것은 이 규칙을 위반하는 것입니다.
해결책: Dispatcher 활용
이 문제를 해결하는 열쇠는 UI 업데이트가 올바른 스레드에서 발생하도록 보장하는 메커니즘인 디스패처를 사용하는 것입니다. 여기에는 간단하면서도 효과적인 패턴이 포함됩니다.
대리자 만들기: UI 업데이트 작업을 캡슐화하는 대리자 정의:
<code class="language-csharp">delegate void SetTextCallback(string text);</code>
업데이트 메서드 구현: 이 메서드는 현재 스레드가 UI 스레드인지 확인합니다. 그렇지 않은 경우 Invoke
을 사용하여 업데이트를 UI 스레드로 마샬링합니다.
<code class="language-csharp">private void SetText(string text) { if (this.textBox1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.textBox1.Text = text; } }</code>
백그라운드 스레드에서 업데이트: serialPort1_DataReceived
이벤트 핸들러(또는 이와 동등한 것)에서 데이터를 수신한 후 SetText
메서드를 호출합니다.
<code class="language-csharp">private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { string receivedData = serialPort1.ReadExisting(); SetText(receivedData); }</code>
이 접근 방식을 사용하면 모든 UI 업데이트가 기본 UI 스레드에서 안전하게 수행되어 크로스 스레드 예외가 방지됩니다. InvokeRequired
검사는 업데이트가 이미 올바른 스레드에 있는 상황을 효율적으로 처리하여 불필요한 오버헤드를 방지합니다.
위 내용은 크로스 스레드 예외를 방지하기 위해 C#의 별도 스레드에서 UI 컨트롤을 안전하게 업데이트하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!