Последовательная связь с низкой задержкой в ​​.Net

Я исследовал различные сторонние библиотеки и подходы к последовательной связи с малой задержкой в ​​.Net. Я прочитал достаточно, чтобы пройти полный круг и знать так же мало, как и в начале, из-за множества противоречивых мнений.

Например, функциональность в фреймворке была исключена из-за некоторых убедительных статей, в которых говорилось: «предоставленное Microsoft решение не было стабильным в разных версиях фреймворка и ему не хватало функциональности».

Я нашел статьи, критикующие многие старые библиотеки на основе COM. Я нашел статьи, критикующие идею приложения .Net с малой задержкой в ​​целом из-за сборки мусора.

Я также читал статьи, демонстрирующие неприемлемость функции P/Invoking Windows API для связи с малой задержкой.

ЭТО ИСКЛЮЧАЕТ ЛЮБОЙ ПОДХОД, КОТОРЫЙ Я МОГУ ПРИДУМАТЬ!

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

  • Устойчивая последовательная связь с малой задержкой в ​​C# / VB.Net
  • 32/64 бит
  • Хорошо документировано (если решение стороннее)
  • Относительно незатронутая (с точки зрения связи и задержки) сборка мусора.
  • Гибкость (я понятия не имею, с чем мне придется взаимодействовать в будущем!) Единственное требование, которое у меня есть наверняка, заключается в том, что мне нужно иметь возможность взаимодействовать со многими различными промышленными устройствами, такими как линейные приводы на основе RS485, последовательные / микроконтроллеры. датчики на основе и устройства ModBus (также RS485).

Любые комментарии, идеи, мысли или ссылки на статьи, которые могут сгладить мое замешательство, очень ценятся!


person Berney Villers    schedule 27.04.2010    source источник


Ответы (5)


У меня есть приложение .NET, которое работает на сервере с 16 COM-портами, около 11 из которых в настоящее время подключены к различным устройствам, некоторые RS485, многие RS-232. (Диаграмма здесь: http://blog.abodit.com/2010/03/home-automation-block-diagram/). Большинство этих устройств работают со скоростью всего 9600 бод, и большинство из них не имеют очень жестких требований к времени. У меня есть поток для каждого устройства, обрабатывающего получение, и хотя он работает с нормальным приоритетом потока, все остальные потоки, не связанные с связью, работают с более низким приоритетом (как и в любом случае для большинства фоновых задач). У меня не было проблем с этой настройкой. И, кстати, он также воспроизводит музыку на трех звуковых картах одновременно, используя высокоприоритетные потоки из управляемого кода и 1-секундные буферы DSound, и все это без сбоев.

Итак, насколько жесткие у вас требования к задержке, какая скорость передачи данных и сколько последовательных портов вы пытаетесь обслуживать? Буфера на вашем UART при большинстве нормальных скоростей передачи данных более чем достаточно для сборки мусора и гораздо больше, чтобы отложить удаление следующего байта.

GC не такое зло, как его изображают. В правильно расставленной поточной системе с хорошим управлением размерами и временем жизни объектов и достаточной буферизацией (UARTS/звуковые буферы и т. д.) он может работать очень хорошо. Microsoft также постоянно совершенствует его, и теперь .NET Framework 4 обеспечивает сборку мусора в фоновом режиме. Эта функция заменяет параллельную сборку мусора в предыдущих версиях и обеспечивает более высокую производительность. См. MSDN.

person Ian Mercer    schedule 27.04.2010
comment
Спасибо за внимание к улучшениям GC. Этот сценарий максимальной производительности, которого мне нужно достичь, — это связь с линейным приводом на частоте 250 Гц. Если на самом деле GC не является проблемой, то дальше все сводится к тому, какой тип задержки вводится фреймворком или P/Invoke. - person Berney Villers; 29.04.2010
comment
Большинство соединений будут на скорости 115200 бод, но некоторые будут выше. - person Berney Villers; 29.04.2010

Задержка не является проблемой на современных машинах. Последовательные порты очень медленные, 19,2 КБод — это пустяки, класс .NET SerialPort прекрасно с ними справляется. Событие DataReceived доставляется асинхронно потоком пула потоков, который выполняет ожидание блокировки с помощью WaitCommEvent(), вы не можете работать быстрее.

person Hans Passant    schedule 27.04.2010
comment
Попробуйте простейший подход с тестовой установкой и посмотрите, есть ли у вас проблемы, прежде чем углубляться в эзотерику. - person dkretz; 23.06.2010
comment
Драйвер последовательного порта имеет буферы, поэтому он может обрабатывать пропускную способность. Пропускная способность — это не то же самое, что задержка/оборот, например. OP может захотеть последовательно передать сообщение в течение мс после получения сообщения. - person ChrisW; 23.06.2010
comment
Задержка — огромная проблема на современных машинах. В моем случае я обрабатывал событие datareceived класса SerialPort. Он выполняет обработчик событий в отдельном потоке. Задержка, вызванная простым использованием обработчика событий, была просто неприемлема для моего приложения. Вы можете отправить столько данных, сколько хотите, правда. Но проблема в том, как быстро вы заметите, что получили новые данные. - person Cedric Mamo; 13.06.2013

.NET, как правило, плохой выбор для описываемого вами приложения. Для такого рода вещей потребуется нативный код и язык вроде C++, по крайней мере, для той части, которая требует малой задержки.

person Tom Cabanski    schedule 27.04.2010
comment
Моя цель — связь на частоте 250 Гц с линейным приводом в самом экстремальном сценарии. Ваше мнение об этом связано со сборкой мусора, дополнительной задержкой, добавленной P/Invoke, или каким-то другим элементом, который я упускаю из виду? - person Berney Villers; 29.04.2010
comment
@bvillersjr - я думаю, что неуправляемому потоку можно установить более высокий приоритет, чем управляемому потоку. Таким образом, написав собственную DLL, которая использовала неуправляемые потоки, мы однажды добились низкой задержки, когда взаимодействовали с USB-драйверами, которые имели небольшие буферы и, следовательно, устанавливали жесткие временные рамки для приложения. - person ChrisW; 23.06.2010

Лично мне нравится мой интерфейс BBUSB. При переключении в режим Bitbang он позволяет вам напрямую включать/выключать 8 контактов, которые вы можете установить как вход или выход.

«Но мне нужен последовательный порт». Ты говоришь. Это вполне возможно. Просто подключите контакты к 9-контактному последовательному порту, и все готово.

person Spencer Ruport    schedule 27.04.2010
comment
Ссылка мертва. Опрятный сайт однако. - person kfm2000; 26.10.2011
comment
Я так понимаю, они перестали его продавать? Это неудачно. - person Spencer Ruport; 26.10.2011

Класс последовательного порта .Net потребляет слишком много ресурсов ЦП при отправке небольших пакетов на высоких частотах. Также кажется, что некоторые события пропущены. Поскольку мне нужно было надежно отправлять и получать 16-байтовые пакеты 1000 раз в секунду, я собрал что-то, основанное на Windows API, и теперь могу легко запускать 1000 небольших пакетов в секунду, практически не потребляя ЦП. Я попробовал почти все доступные библиотеки, и из-за этой простой задачи все они потерпели неудачу из-за чрезмерной загрузки ЦП или пропущенных событий.

person Berney Villers    schedule 17.12.2011