C#Serial DataReceived事件挨饿

时间:2014-10-09 15:07:09

标签: c# multithreading serial-port

我正在现有应用程序之上构建并使用C#SerialPort类来处理USB上的数据事务。我注意到当应用程序生成许多长时间运行的线程并且没有使用TaskCreation LongRunning选项将它们指定为长时间运行时,这些线程可以暂时使SerialPort DataReceived事件饿死并阻止它触发某些扩展时间量。

这是C#处理线程管理方式的一些基本结果吗?

有没有办法增加"优先级" DataReceived事件?

如果没有,那么"解决方案"是否有一个不断运行的线程来轮询串口数据标志,而不是使用DataReceived事件?

谢谢!

2 个答案:

答案 0 :(得分:1)

这是非常基本的,是的。您的DataReceived事件处理程序由线程池线程调用。如果你有太多的活动用于其他目的,比如不是LongRunning的任务,那么在你的事件处理程序运行之前可能需要一段时间。在完成I / O调用时提升线程优先级的正常操作系统调度算法在这里是无效的,它只能有效地调度tp线程:)

这是一个基本的消防水管问题,您期望机器完成的工作量超出其能力。通过查看任务管理器来了解您是否正确行事的方法。 CPU使用率应固定为100%。如果它大大少于你没有有效地使用线程池,一些任务正在占用池但没有执行足够的代码,通常是因为它们在同步对象或我等待太多/ O操作完成。你应该通过使用普通的Thread或TaskCreationOptions.LongRunning来解决这个问题。 ThreadPool.SetMinThreads()经常被引用作为快速修复,它是一个脏的。升级机器规格,更多内核,更简洁。

答案 1 :(得分:1)

这是一个更简单的解决方案 - 按照设备驱动程序编写者的意图使用串行端口。绝对没有任何关于串行端口通信的保证使用工作线程,无论是手动创建还是从线程池。我们建议您阅读我的整篇博文"If you must use .NET System.IO.Ports.SerialPort",但如果您使用的是最新版本的.NET,那么简短版本就是BaseStream.ReadAsyncasync + await一起使用,和BaseStream.BeginRead否则回调。

另外,感谢您提供DataReceived事件可怕的另一个原因。这份清单已经很长了。