2013-07-05 1 views
0

Сегодня я сталкиваюсь с каким-то странным поведением. У меня есть последовательное устройство, к которому я обращаюсь, используя класс SerialPort. Основное приложение имеет некоторый таймер, который опросает каждую секунду устройство для некоторого обновления состояния. В какой-то момент мне нужно сделать много времени на работу и, следовательно, не блокировать GUI, я использовал Backgroundworker. Для доступа к одному и тому же последовательному устройству фоном требуется один раз. Иногда доступ иногда работает. Классический сценарий mutli-thread. Поэтому я попытался использовать Mutex для функции, которая отправляет новую команду на последовательное устройство.C# несколько потоков и последовательная связь

Для последовательного устройства я все собрал в своем классе. В этом классе у меня есть функция sendCommand(), которая записывает команду на устройство и использует AutoResetEvent и событие OnDataReceived для ожидания ответа. Функция sendCommand блокирует до получения ответа или тайм-аута. Затем я добавил Mutex при вводе sendCommand и releaseMutex во все возможные выходы. Все еще не работает.

Есть ли лучший способ справиться с этим?

Спасибо, Tobias

+0

releaseMutex? Работа с C#? Просто оберните всю функцию внутри оператора lock()? –

+0

Вы видите сообщение об ошибке или приложение блокируется в ожидании выхода мьютекса? –

+0

Ваше устройство не поддерживает дуплексный канал? – Suhan

ответ

1

У меня есть приложение, которое делает это одно и то же - то, что я сделал, я создал серийный класс доступа и всякий раз, когда я бы назвал его (или из графического интерфейса или один из моих background threads) У меня бы получилось:

private void myFunction(SerialClass myserialobject) { 
    if (myserialobject == null) 
    return; 
    lock (myserialobject) { 
    // code accessing the serial object 
    // ... 
    // when finished, close the lock statement 
    } 
} 

Я использовал это как в основном потоке, так и в любых других потоках, требующих доступа. Он блокирует, но я считаю, что это блокирующий оператор.

Кроме того, вместо использования обработчика событий для события OnDataReceived я сделал, чтобы мой последовательный объект выполнял блокировку чтения после любой записи, тем самым предотвращая получение данных в неправильном контексте. Я не уверен, как именно ваша программа настроена, но вы можете подумать об этом. Он лучше всего работает, если вы знаете количество байтов, которое вы ожидаете читать при записи в порт; таким образом вам не придется использовать Sleep, чтобы убедиться, что все данные были прочитаны.

+0

Благодарим вас за предложение. Я не знаю, сколько байтов получить. Это протокол типа ASCII, где команда ограничена символами новой строки. После того, как я получил пустую строку, я должен разобрать и проверить, что я получил раньше. Это может быть что угодно от нуля до четырех. Поэтому я использую 'OnDataReived' и записываю все в буфер до получения пустой строки. Затем я устанавливаю 'AutoResetEvent', чтобы сигнализировать мою процедуру« SendCommand »для обработки данных. Блоки «SemdCommand» блокируются до тех пор, пока не будут получены данные или не произойдет тайм-аут. – thefloe

0

Что я обычно делаю, это запустить последовательный поток чтения/записи в цикле, считывая команды из BlockingQueue с временным ожиданием. Если в течение таймаута принимается объект последовательного запроса, поток выполняет его, если время ожидания истекает, поток формирует опрос последовательного устройства.

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