2012-03-29 7 views
2

Ok。私は2つのCOMポートを監視するプログラムを持っています。 1つはスケールに引っかかり、もう1つはモデバスボードに引っ掛けられます。C#BackgroundWorkerとComポートの問題

私の問題は、Modbusボードに接続されているCOMポートにあります。私のプログラムは、100MSごとにセンサー(modbusボード上)を読み取っています。センサーがブロックされているかどうかを判断するために、COMポート経由で0または1を返します。ブロックされている場合は、信号がポートを介してボードに送信されます。

私の問題は、センサーの監視を終了できませんが、他の信号を送信する前にcomポートが使用されていないことを確認する必要があります。

センサを監視するルーチンは、背景作業者のスレッドにあります。センサーがトリップすると、別のスレッドが生成され、信号がモデバスボードに送信されます。だから私はボードに信号を送信している間に "センサースレッド"を一時停止する必要があります。これをどうやってやりますか?

これはBackgroundWorkerなので、Thread.Joinはオプションではありません。

private void SensorThread_DoWork(object sender, DoWorkEventArgs e) 
    { 
     if (SensorThread.CancellationPending == true) 
      e.Cancel = true; 
     else 
     { 
      ReadSensor(); 
     }  
    } 

このスレッドのRunWorkerCompletedだけのスレッドを再起動します。

は、ここに私のコードです。 次のスレッドが常にセンサーがブロックされているときに表示する「sensorstatus」を監視している:

public void ScaleThread_DoWork(object sender, DoWorkEventArgs e) 
    { 
     if (ScaleThread.CancellationPending == true) 
     { 
      e.Cancel = true; 
     } 
     else 
     { 
      //sensor is blocked 
      if (sensorstatus == 0) 
      { 
       ReadScale(); 
       prevgate = gate; 
       gate = DetermineGate(); 
       //SaveData(); 
       SetOpenDelay(); 
       SetDuration(); 
       //no gate was selected, meat out of range, runs off end 
       if (gate == 0) 
       { 
        txtStatus.Invoke(new UpdateStatusCallback(UpdateStatus), new object[] { meatweight.ToString() + 
                        "lbs is out of range"}); 
       } 
       else 
       { 
        //this triggers a thread to send a signal to the modbus board 
        gateTimer.Start(); 
       } 
      } 
     } 
    } 

RunWorkerCompletedはこのためにそれループ

+3

このようなタスクの場合、私は 'BackgroundWorker'はあなたが選べる最悪の解決策だと思います。 'x'秒ごとに監視する必要のあるものがあれば、' while'ループと 'Thread.Sleep(x);を持つ伝統的な' Thread'がはるかに適しています... –

答えて

4

がALLの送信を担当する単一のスレッドを作成すること、このスレッドを再開しますオペレーション。このスレッドにメッセージを送信してデバイスに送信するキューを実装します。これを簡単に実装するには、新しいBlockingCollection<T>を使用することができます。 http://msdn.microsoft.com/en-us/library/ee789351.aspx

は今、あなたは、単にタスクの火がデバイスに送信することができ、それらは順次実行されます - :TPLを使用して

OR、ここに示すように、1の並列性の限られた程度でTaskSchedulerを作成します。

送信者と読者の間で情報をやりとりする必要がある場合を除き、私は読者の操作を独自のスレッドで実装します。