2

Visual C# / .Net アプリケーションでは、SerialPort を読み取る必要があるため、DataReceivedEventHandler を割り当てました。

ただし、もちろんハンドラーから UI コントロールを直接変更することはできません。それらは別のスレッド上に存在するからです。

解決策は Control.Invoke を使用することですが、実行する UI アクションが多すぎるため、おそらく正しい道をたどっていないのではないかと心配しています。

次のうちどれを行う必要がありますか?

  • オプション A:とにかくInvokeを使用し、さまざまなコントロールのそれぞれに対して Invoke を使用してそれぞれのアクションを実行します。

  • オプション B: 50 ミリ秒の繰り返しタイマーを配置します。50 ミリ秒ごとにブール値のDataReceived == trueかどうかを確認し、そうであればそれに応じて UI コントロールを更新します。(シリアル ポート DataReceivedEventHandler でデータを読み取るたびに DataReceived を true に設定し、それ以外の場合は false に設定します。)

  • 選択肢 C: 他に選択肢はありますか?

アップデート:

次の成功 (@tcarvin の回答と @Hans Passant のコメントに基づく)。

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
   if (this.InvokeRequired())
   {
      this.BeginInvoke(new EventHandler<SerialDataReceivedEventArgs>(DataReceivedHandler), new object[] { sender, e });
      return;
   }

   tbSerialStatus.Text = "Received text";    
}
4

2 に答える 2

4

あなたはこれを考えすぎていると思います。フォーム内でコーディングしていると仮定すると、このようなものが機能するはずです。これは腰からのものです。少し微調整する必要があるかもしれません。

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{

   if (this.InvokeRequired)
   {
      this.Invoke(new EventHandler<SerialDataReceivedEventArgs>(DataReceivedHandler), sender, e);
      return;
   }

   // everything here runs on the UI thread, do what you like, 
   // and update as many UI controls as you like.

}

ご覧のとおり、各コントロールへのアクセスを個別の でラップする必要はありませんControl.Invoke

于 2013-07-11T12:35:44.623 に答える
0

解決しました。このアプローチは機能します:

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
   if (this.InvokeRequired())
   {
      this.BeginInvoke(new EventHandler<SerialDataReceivedEventArgs>(DataReceivedHandler), new object[] { sender, e });
      return;
   }

   tbSerialStatus.Text = "Received text";    
}
于 2013-07-11T13:36:11.423 に答える