2012-03-29 3 views
2

Хорошо. У меня есть программа, которая контролирует 2 COM-порта. Один подключен к шкале, а другой подключен к плате Modbus.Проблемы с C# BackgroundWorker и Com Port

Моя проблема в COM-порту, подключенном к плате Modbus. Моя программа считывает датчик (на плате Modbus) каждые 100MS. Он возвращает 0 или 1 (через COM-порт), чтобы определить, заблокирован ли датчик. Если он заблокирован, сигнал посылается через порт на плату.

Моя проблема заключается в том, что я не могу прекратить наблюдение за датчиком, но я должен быть уверен, что COM-порт не используется до отправки моего другого сигнала.

Подпрограмма, которая контролирует датчик, находится на рабочей поверхности рабочего стола. Как только датчик сработает, появляется другая нить, которая посылает сигнал на плату 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 для этого перезапускает эту нить, что делает его петлю

+3

Для такой задачи я думаю, что «BackgroundWorker» - самое худшее решение, которое вы можете выбрать. Если у вас есть что-то, что нужно отслеживать каждые «х» секунд, традиционный «поток» с циклом «while» и «Thread.Sleep (x);» гораздо более подходит ... –

ответ

4

Создать единую нить, ответственную за все отправить операции. Реализуйте очередь, которая передает этот поток сообщениям для отправки на устройство. Вы можете использовать новый BlockingCollection<T>, чтобы реализовать это легко.

OR, используя TPL, создать TaskScheduler с ограниченной степенью параллельности 1, как показано здесь: - http://msdn.microsoft.com/en-us/library/ee789351.aspx

Теперь вы можете просто огонь Задачи для отправки на устройство, и они будут выполняться последовательно.

Если нет необходимости связывать информацию между отправителем и читателем, я бы выполнил операцию чтения в отдельном потоке.

Смежные вопросы