C# BackgroundWorker and Com Port Problems

谁说胖子不能爱 提交于 2019-12-07 14:37:30

问题


Ok. I have a program that monitors 2 COM ports. One is hooked to a scale and the other is hooked to a modbus board.

My problem is in the COM port attached to the modbus board. My program is reading a sensor (on the modbus board) every 100MS. It returns a 0 or 1 (over the COM port) to determine whether the sensor is blocked. If it is blocked, a signal is sent over the port to the board.

My problem is I can't quit monitoring the sensor, but I have to be sure the com port is not in use before sending my other signal.

The routine that monitors the sensor is on a backgroundworker thread. Once the sensor is tripped, another thread is spawned that sends a signal to the modbus board. So I need to pause the "sensor thread" while I'm sending a signal to the board. How would I go about doing this?

Remember it is a BackgroundWorker, so Thread.Join is not an option.

Here is my code:

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

The RunWorkerCompleted for this thread just restarts the thread. The following thread is constantly monitoring the "sensorstatus" to see when the sensor is blocked:

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();
                }
            }
        }
    }

The RunWorkerCompleted for this restarts this thread, making it a loop


回答1:


Create a single thread responsible for ALL send operations. Implement a Queue that feeds this thread with messages to send to the device. You can use the new BlockingCollection<T> to implement this easily.

OR, using TPL, create a TaskScheduler with a limited degree of parallelism of 1 as shown here:- http://msdn.microsoft.com/en-us/library/ee789351.aspx

Now you can simply fire of Tasks to send to the device and they will execute sequentially.

Unless there is some need to communicate information between the sender and the reader I would implement the reader operation on its own separate thread.



来源:https://stackoverflow.com/questions/9932752/c-sharp-backgroundworker-and-com-port-problems

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!