.NET中的低延迟串行通信

5

我一直在研究各种第三方库和低延迟串行通信的 .Net 方法。我已经读了很多文章,但由于不同意见的多样性,现在我知道的比开始时还少。

例如,由于某些令人信服的文章指出:“Microsoft 提供的解决方案在框架版本之间不稳定,并且缺乏功能”,因此 Framework 中的功能被排除在外。

我找到了许多抨击旧版基于 COM 的库的文章。我也发现了一些关于低延迟 .Net 应用程序的想法有问题,因为会涉及到垃圾回收。

我还阅读了一些关于使用 Windows API 进行 P/Invoke 的文章,以实现低延迟通信,但这种方法并不可取。

这几乎排除了我能想到的任何方法!

我真的希望从那些有相关经验的人那里得到一些建议。理想情况下,我可以找到一个可靠的库或合作伙伴,而不必自己构建通信库。我有以下简单的目标:

  • 在 C# / VB.Net 中保持持续低延迟的串行通信
  • 32/64 位
  • 有良好的文档(如果解决方案是第三方的)
  • 在垃圾回收方面相对不受影响(通信和延迟方面)。
  • 灵活(我不知道将来需要与哪些工业设备进行接口!)唯一确定的要求是,我需要能够与许多不同的工业设备进行接口,例如 RS485 线性执行器、串行/微控制器基础计量仪表和 ModBus(也是 RS485)设备。

非常感谢您提供任何评论、想法、思路或可以消除我的困惑的文章链接!

5个回答

3

现代计算机上的延迟不是问题。串口速度非常慢,19.2千波特几乎可以忽略不计,.NET SerialPort类可以很好地处理它们。DataReceived事件由线程池线程异步传递,使用WaitCommEvent()进行阻塞等待,您无法更快。


在深入研究之前,先尝试使用测试装置来尝试最简单的方法,看看是否会出现问题。 - dkretz
串口驱动程序具有缓冲区,因此它可以处理吞吐量。吞吐量与延迟/周转时间不同,例如,操作可能希望在接收到消息后始终在毫秒内传输消息。 - ChrisW
1
延迟是现代机器上的一个巨大问题。在我的情况下,我正在处理SerialPort类的datareceived事件。它会在单独的线程上执行事件处理程序。仅仅使用事件处理程序引入的延迟对于我的应用程序来说是完全不可接受的。你可以发送任意数量的数据,没错。但问题是“你多快能注意到你已经收到了新数据”。 - Cedric Mamo

2
我有一个.NET应用程序,运行在一个具有16个COM端口的服务器上,其中大约11个端口当前连接到各种设备,有些是RS485,许多是RS-232。(如图所示:http://blog.abodit.com/2010/03/home-automation-block-diagram/)。这些设备中大部分都只运行在9600波特率,并且大多数都没有非常严格的时序要求。我有一个线程处理每个设备的接收,虽然它以正常的线程优先级运行,但所有其他非通信线程都以较低的优先级运行(无论什么情况下,对于大多数后台任务都应该这样做)。我使用这个设置没有遇到任何问题。另外,顺便说一下,它还可以使用来自托管代码的高优先级线程和1秒钟的DSound缓冲区同时播放三个声卡中的音乐,而不会出现故障。

那么你的延迟要求有多紧?你要服务的波特率和串口数量是多少?在大多数正常波特率下,UART上的缓冲区足够用于垃圾回收,而且更多的是为了延迟获取下一个字节。

垃圾回收并不像人们所说的那样邪恶。在一个正确设置优先级的线程系统中,管理对象大小和生命周期,并有足够的缓冲区(UARTS /声音缓冲等),它可以表现得非常出色。微软还在不断改进它,.NET Framework 4现在提供后台垃圾回收功能。这个功能替换了以前版本的并发垃圾回收,并提供更好的性能。参见MSDN。


感谢您提供有关GC改进的信息。我需要实现的最高性能场景是与线性执行器进行250Hz通信。如果实际上GC不是问题,那么接下来就要看框架或P/Invoke引入了什么类型的延迟。 - Berney Villers
大多数连接速率将为115200波特,但有些会更高。 - Berney Villers

1

.NET通常不是您所描述的应用程序的好选择。这种类型的应用程序需要本地代码和像C++这样的语言,至少需要具备低延迟的部分。


我的目标是在最极端的情况下,与线性执行器进行250Hz通信。你对此的看法是由于垃圾收集,还是由于P / Invoke或其他我忽略的因素添加的额外延迟? - Berney Villers
@bvillersjr - 我认为非托管线程可以设置比托管线程更高的优先级。编写一个使用非托管线程的本地DLL,正是我们在与具有小缓冲区且对应用程序施加紧密时序要求的USB驱动程序进行接口时实现低延迟的方法。 - ChrisW

0

个人而言,我喜欢我的BBUSB接口。当切换到位控模式时,它允许您直接控制8个引脚的开关状态,您可以将其设置为输入或输出。

“但我需要一个串口。”你说。这完全是可能的。只需将引脚连接到9针公头串口上,就可以使用了。


链接已失效。不过网站很整洁。 - kfm2000
我猜他们停止销售了?那很不幸。 - Spencer Ruport

0

.Net串口类在高频率发送接收小数据包时消耗的CPU过多,而且似乎会错过一些事件。由于我需要能够可靠地每秒发送和接收1000个16字节的数据包,所以我基于Windows API组合了一些东西,现在可以轻松地每秒触发1000个小数据包,同时几乎不消耗CPU。我尝试了几乎所有可用的库,但对于这个简单的任务,它们都因为过度使用CPU或错过事件而失败。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接