3

Ok。2 つの COM ポートを監視するプログラムがあります。1 つはスケールに接続され、もう 1 つは Modbus ボードに接続されています。

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

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

センサーを監視するルーチンは、backgroundworker スレッドにあります。センサーが作動すると、Modbus ボードに信号を送信する別のスレッドが生成されます。そのため、ボードに信号を送信している間は「センサー スレッド」を一時停止する必要があります。どうすればこれを行うことができますか?

これは 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 は、このスレッドを再起動し、ループにします

4

1 に答える 1

5

すべての送信操作を担当する単一のスレッドを作成します。このスレッドにメッセージをフィードしてデバイスに送信するキューを実装します。newを使用して、BlockingCollection<T>これを簡単に実装できます。

または、TPLを使用しTaskSchedulerて、次のように1の限定された並列度でを作成します。-http://msdn.microsoft.com/en-us/library/ee789351.aspx

これで、タスクを起動してデバイスに送信するだけで、タスクが順番に実行されます。

送信者とリーダーの間で情報を通信する必要がない限り、リーダー操作を独自の別のスレッドで実装します。

于 2012-03-29T20:19:57.850 に答える