C # BackgroundWorker и проблемы с Com-портом - PullRequest
3 голосов
/ 30 марта 2012

Хорошо.У меня есть программа, которая контролирует 2 COM-порта.Один подключен к весам, а другой - к плате Modbus.

Моя проблема в COM-порту, подключенном к плате Modbus.Моя программа читает датчик (на плате Modbus) каждые 100 мс.Он возвращает 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 для этого потока просто перезапускает поток.Следующий поток постоянно отслеживает состояние датчика, чтобы увидеть, когда датчик заблокирован:

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 для этого перезапускает этот поток, превращая его в цикл

1 Ответ

5 голосов
/ 30 марта 2012

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

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

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

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

...