ホームページ >バックエンド開発 >C++ >C# の非 UI スレッドから UI コントロールを安全に更新するにはどうすればよいですか?

C# の非 UI スレッドから UI コントロールを安全に更新するにはどうすればよいですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2025-01-23 02:27:10881ブラウズ

How to Safely Update UI Controls from Non-UI Threads in C#?

C# クロススレッド操作の検証: 非 UI スレッドからのコントロールへのアクセス

コントロールを作成したスレッド以外のスレッドで UI 要素 (TextBox など) にアクセスすると、「無効なクロススレッド操作: コントロール 'textBox1' に、コントロールを作成したスレッド以外のスレッドからアクセスしています」という例外が発生することがあります。作成しました」。これは、各 UI 要素がイベントと変更を処理するための特定のスレッドに関連付けられているためです。

この例では、serialport1_DataReceived イベント ハンドラーから textBox1 コントロールを更新しようとしています。シリアル ポート操作の非同期性により、このハンドラーは別のスレッドで実行されます。

解決策:

この問題を解決し、非 UI スレッドから textBox1 コントロールに安全にアクセスするには、UI 要素とのすべての対話がメイン (UI) スレッドで呼び出されるようにする必要があります。これは、クロススレッド通信メカニズムを提供し、UI 更新が正しいスレッドで確実に実行されるようにするスケジューラーを使用して実現できます。

以下は、委任されたセキュリティ更新 textBox1 コントロールを使用した serialport1_DataReceived メソッドの修正バージョンです。

<code class="language-csharp">private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
  // 在UI线程上更新'txt'变量
  txt += serialPort1.ReadExisting().ToString();

  // 使用委托在UI线程上访问'textBox1'控件
  SetTextCallback d = new SetTextCallback(SetText);
  this.Invoke(d, new object[] { txt.ToString() });
}

private delegate void SetTextCallback(string text);

private void SetText(string text)
{
  // 检查'textBox1'控件是否在不同的线程上创建
  if (this.textBox1.InvokeRequired)
  { 
    this.Invoke(d, new object[] { text });
  }
  else
  {
    // 如果在UI线程上创建,则直接更新'textBox1'控件
    this.textBox1.Text = text;
  }
}</code>

このアプローチを使用すると、textBox1 コントロールが常にメイン (UI) スレッドでアクセスおよび変更されるようになり、クロススレッド操作の例外が解決されます。

以上がC# の非 UI スレッドから UI コントロールを安全に更新するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。