C# マルチスレッド アプリケーションでの「クロススレッド操作が無効です」例外の処理
複数のスレッドを使用する C# アプリケーションでは、UI 要素の作成を担当するスレッドが UI 要素に排他的にアクセスできるようにすることが重要です。 この原則に違反すると、恐ろしい「クロススレッド操作が無効です」という例外が発生します。
C# スレッドと UI 要素の所有権を理解する
C# では、複数のスレッドによる同時実行が可能です。各スレッドは、独自のコンテキスト内で独立して動作します。 重要なのは、UI 要素 (テキスト ボックスなど) は特定のスレッド、通常はメイン UI スレッドに属していることです。
問題: 未承認のスレッドから UI 要素にアクセスする
このエラーは、所有スレッド以外のスレッドが UI 要素のプロパティを変更しようとすると発生します。 これは一般的なシナリオであり、バックグラウンド スレッドからのイベント (シリアル ポート データ受信など) を処理するときによく発生します。
解決策: ディスパッチャ呼び出しの実装
この解決策には、ディスパッチャーを使用して操作を正しいスレッドにマーシャリングすることが含まれます。 これにより、UI コントロールのスレッドセーフな変更が保証されます。
コードの実装
このソリューションを実装する方法は次のとおりです:
まず、デリゲートを定義します。
<code class="language-csharp">private delegate void SetTextCallback(string text);</code>
次に、テキスト ボックスを安全に更新するメソッドを作成します。
<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>
最後に、シリアル ポート データ受信イベント ハンドラー内で、SetText
メソッドを呼び出します。
<code class="language-csharp">private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { txt += serialPort1.ReadExisting(); SetText(txt); }</code>
このアプローチにより、textBox1.Text
プロパティが安全に更新され、「クロススレッド操作が無効です」例外が回避されます。 InvokeRequired
チェックは、ディスパッチャ呼び出しが必要かどうかを効率的に判断します。
以上がC# マルチスレッドでの「クロススレッド操作が無効です」エラーを解決する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。