2012-02-14 5 views
0

シリアルポート経由でバイトを送受信するSerialClientというクラスがあります。 SerialClient.Start()が呼び出されると、無限のwhileループに入り、SerialClient.Stop()が呼び出されます。クラスにはいくつかのプロパティがありますが、簡略化のためにSerialClient.PropASerialClient.PropBと言うことができます。MVPを使用してスレッドでシリアルポートを実行しています

私はこれをGUIで使用する必要があります。 GUIのどこで、開始、停止、プロパティの変更を読み込むことができますか。

GUIでこれを使用するには、明らかにSerialClientを無限ループとしてスレッドで操作する必要があります。だから、私はSerialClientのそれに一致するプロパティを持つビューをセットアップしました。ビューは、発表者のStart()Stop()を呼び出します。

私は新しいスレッドを作成し、SerialClientのオブジェクトでstartを呼び出します。問題は、_serialClientがプレゼンターがキャッチできない例外をスローし、(SerialClient.PropB)のようなプロパティが変更され、変更されたイベントハンドラーを呼び出す場合、GUIスレッド上で呼び出される必要があります。私はバックグラウンドワーカーを使用しようとしましたが、それを動作させることができませんでした(プロパティの変更は、まだUI以外のスレッドからUIにぶつかります)。

Thread thread = new Thread(_serialClient.Start); 
thread.IsBackground = true; 
thread.Start(); 

私が見ている簡単な解決策が必要です。 GUIは単にメソッドを呼び出してプロパティを読み込み、例外がアプリケーション全体をクラッシュさせないようにするだけです。

アイデア?

+0

あなたはErrorReceivedとDataReceivedを処理しています¿か? –

+0

.Net SerialPortクラスについてそうでなければ。 SerialClientクラス内。 OpenCOM()メソッドがあります。これにより、正しい設定でCOM5にSerialPort(_comport)が作成され、それが開きます。このすべてはStart()内にあり、OpenCOM()が呼び出された後、無限ループを含むSendReceivedDataメソッドに対して新しいスレッドが作成されます。ここでは、データがある場合は_comport.BytesToReadを読み取り、_comport.Read(/ *ここでデータを読み込みます* /)、送信するデータがある場合は_comport.Writeを使用します(/ * my data here//) 。 – JonWillis

+0

はい、バイトをループを使用しないでください。DataReceivedイベントでエラーを試してください。可能であればエラーに対してErrorRecievedを実行してください。その後、シリアルポートによってDataReceivedが呼び出されると、すべてのデータを読み込み、デリゲートを呼び出します。 –

答えて

1

あなたは、C#で、マルチスレッドアプリケーションを扱うときに通常見られる一般的な問題の2ヒット:バックグラウンドスレッドで例外への対処

  1. を。バックグラウンドスレッドで例外が発生すると、呼び出し元から呼び出し元にスタックを移動し、その例外を捕まえることができるかどうかを確認します。元のコールが自分のコールの外から発生した場合(たとえば、シリアルポートまたはタイマーからのコールバック)、例外が通知される場合と通知されない場合があります。これに対する典型的な解決策として、私が見てきたことは、例外をスローするコードをtry-catchで囲み、イベントハンドラに例外を適切に処理できるスレッドに例外をプッシュさせることです(ログ、ユーザーに通知する、上記のすべてを終了する)

  2. イベントは常にそれらを呼び出すスレッドで実行されます。 DispatcherとInvokeを使用してUIスレッドへの呼び出しを手動でマーシャリングする必要があります。私が見つけたそれを行うための最もsuccintコードhere


void someEvent_Handler(object sender, SomeEventEventArgs e) 
{ 
    if (this.Dispatcher.CheckAccess()) 
    { 
     // do work on UI thread 
    } 
    else 
    { 
     // or BeginInvoke() 
     this.Dispatcher.Invoke(new Action(someEvent_Handler), 
      sender, e); 
    } 
} 
+0

を使用しているときに、すべての呼び出しハンドラを記述することです。私はスレッドを開始するコードを含む開始メソッドを持っているので、他の人へのAPiは簡単です。それから私はExceptionRaisedと呼ばれるイベントを持っています。これは、スレッドメソッドをエスケープする例外が発生したときに呼び出されます。このようにして、例外が捕捉されて停止し、スレッドが停止し、イベントが発生します。私はこれが最善の解決策だと思っていますが、私は本当に良い方法がありました。私はGUIスレッドを呼び出すように見ましたが、必要なインターフェイスはコンパクトなフレームワークではありません。 – JonWillis

関連する問題