2013-07-23 5 views
7

私は製造テスト環境でコーディングの一部を手伝っている技術者です。具体的な質問は、C#のイベントを処理することです。 Button_clickだけでなく、特にシリアルポート経由のデータストリームがあり、シリアルポート経由で入ってくるものに応じてリアルタイムでUIを更新する必要がある場合は特にそうです。シリアルポートデータによってトリガされたC#イベントからUIを更新するにはどうすればよいですか?

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) { 
    input = (sender as SerialPort).ReadLine(); 
    if (input.Contains("look for this")) 
     this.Invoke(new EventHandler(doSomething)); 
} 

し、何かのように:

void OnGotData(object sender, EventArgs e) {...}; 
delegate void UpdateCallback(data d); 
void doSomething(data d) { 
    ... 
    if (field.InvokeRequired) { 
      UpdateCallback x = doSomething; 
      this.Invoke(x, new object[] { d }); 
    } 
    else { 
      field.Text = d; 
    } 
    ... 
} 

トレードオフはどのようなものがあり、私は両方が最終的に同じことを行う二つのアプローチを持っている場合たとえば、との違いは何ですか?畳み込まれた第2のアプローチは大会の問題なのですか?リアルタイムパフォーマンスが重要な場合にはどこからでも最初のアプローチを使用することができますか?

+0

二スニペットは非常に紛らわしいです。それは何もしません...デリゲートインスタンスを作成し、それを 'd'変数に代入し、不明なメソッドを宣言し、コンパイルしないデリゲートを宣言します。 –

+0

これは最新の編集で修正する必要があります。コード内の省略記号( "...")は、もともとは分かりやすくするために省略した他のコードの行です。私が知りたいのは、2つのアプローチの間に実際の違いがあった場合です(第2のアプローチが構文的に正しいと仮定し、実際に何かを行ったと仮定して)。 – TerrorTech

+0

構文をより正確にするために、詳細を追加しました。私は明確にするために物事を難読化しており、2つのアプローチの違いの一般的な考え方をもっと探しています。 – TerrorTech

答えて

1

私は理解している場合: 最初のアプローチを - 私たちはコントロールのハンドルが作成されたことがわかっている場合だけで、今UIもの

を行うと - InvokeRequiredが返した場合、真のコールは他呼び出す - 常にUI 第二のアプローチを更新するために呼び出す呼び出し我々はちょうど私たちが最初のアプローチを使用することができ、UIは責任があるが、Invokeのデッドロックを使用することができます小さく、速いUIのアップデートを作ってほしいです。コントロールのハンドルが作成されていない場合は、IsHandleCreatedを呼び出してInvokeが成功し、例外をスローしないようにする必要があります。 IsHandleCreatedがfalseを返す場合、Invokeを使用して更新することはできません。ハンドルが作成されるまで待つ必要があります。

コントロールのハンドルが作成されていない場合にfield.InvokeRequiredがfalseを返す可能性があり、field.Text = d;を呼び出すと、コントロールのハンドルがバックグラウンドスレッドで作成され、メッセージポンプなしのスレッドでコントロールが分離され、アプリケーションが不安定になります。

だから、私のためとして、これは良い方法です:

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) { 
    input = (sender as SerialPort).ReadLine(); 
    if (input.Contains("look for this")) 
    { if (this.IsHandleCreated == false) 
     { 
     //do some stuff to proper handle creation or just wait for handle creation 
     } 

     this.BeginInvoke(new EventHandler(doSomething)); 
    } 
} 
関連する問題