多线程和串行端口

CSh*_*Dev 6 c# multithreading serial-port modbus

好的..这将是冗长的,但我需要首先解释一些背景.

我的软件的这一部分用于分拣传送带上的物品.我正在使用Modbus作为传送带.Modbus将在特定时间打开门,让物品通过大门.物品将根据重量经过某些门.

我正在监控传感器以确定物品何时在秤上.当传感器被阻挡时,物品被称重并被送到适当的门.定时器设置为打开/关闭门.

我的代码将适用于此..问题是,它不适用于多个项目.我的意思是,当门打开时,传感器不会被监控,直到门关闭.因此,当项目A在前往大门的路上时,项目B在阻挡传感器时不会在秤上称重.我一次最多可以有8个项目.这是我现在运行的代码:

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

private void SensorThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    //if sensor is blocked
    if (sensorstatus == 0)
    {
        //the timers just start the thread
        scaleTimer.Start();
    }
    else
    {
        sensorTimer.Start();
    }
}

private void ScaleThread_DoWork(object sender, DoWorkEventArgs e)
{
  if (ScaleThread.CancellationPending == true)
    {
        e.Cancel = true;
    }
    else
    {
        ReadScale();
        //SaveWeight();
        prevgate = gate;
        gate = DetermineGate();
        SetOpenDelay();
        SetDuration();
    }
  }

private void ScaleThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    //if gate = 0, this means the weight of meat on scale 
    //is not in any weight range. Meat runs off the end.
    if (gate == 0)
    {
        txtStatus.Invoke(new UpdateStatusCallback(UpdateStatus), new object[] { meatweight.ToString() + 
                                                                                "lbs is out of range"});
        sensorTimer.Start();
    }
    else
    {
      //open gate
      //then close gate
    }
  }
Run Code Online (Sandbox Code Playgroud)

这段代码工作正常,我只需要能够在线上考虑多个项目.有什么建议????

我也尝试过以下方法:

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

private void SensorThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  sensorTimer.Start();
}

  private void ScaleThread_DoWork(object sender, DoWorkEventArgs e)
{
  if (ScaleThread.CancellationPending == true)
    {
        e.Cancel = true;
    }
    else
    {   
        //sensor blocked
        if (sensorstatus == 0)
        {
          ReadScale();
          //SaveWeight();
          prevgate = gate;
          gate = DetermineGate();
          SetOpenDelay();
          SetDuration();

          //if gate = 0, this means the weight of meat on scale 
          //is not in any weight range. Meat runs off the end.
          if (gate == 0)
          {
            txtStatus.Invoke(new UpdateStatusCallback(UpdateStatus), new object[] { meatweight.ToString() + 
                                                                                "lbs is out of range"});
          }
          else
          {
            //open gate
            //close gate
          }
    }
}

private void ScaleThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
   scaleTimer.Start();
}
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我按下开始按钮时启动了两个线程.我得到各种异常,程序最终抛出SEHException并崩溃.我得到的其他错误说"串口已经打开"或"I/O错误".

sup*_*cat 1

我建议您最好的选择可能是创建一个专用线程来位于每个串行端口上。这种方法既不要求也不禁止端口处理方式的任何相似性,将避免端口之间操作的任何干扰,并且将在合理的范围内进行扩展(对 32 个端口中的每个端口使用一个线程就可以了;使用每 1,000 个线程就很糟糕)。尽管应该避免创建只运行很短时间然后退出的线程,或者创建大量线程,但为每个串行端口使用专用线程将确保当数据传入时有一个线程准备好处理它。