@TomWr你是对的,从我正在阅读的是这种情况。
你下面有我的评语摘录:
try
{
// Let's check how many bytes are available on the Serial Port
btr = serialPort1.BytesToRead;
// Something? Alright then, let's wait 300 ms.
if (btr > 0)
Thread.Sleep(300);
// Let's check again that there are some bytes available the Serial Port
btr = serialPort1.BytesToRead;
// ... and if so wait (maybe again) for 300 ms
// Please note that, at that point can be all cumulated about 600ms
// (if we actually already waited previously)
if (btr > 0)
{
Thread.Sleep(300);
btr = serialPort1.BytesToRead;
numbytes = serialPort1.Read(stuffchar, 0, btr);
for (x = 0; x < (numbytes); x++)
{
// Seems like a useless overhead could directly use
// an Encoding and ReadExisting method() of the SerialPort.
cc = (stuffchar[x]);
stuff += Convert.ToString(Convert.ToChar((stuffchar[x])));
}
我的猜测是同它上面通过idstam已经述及,基本上可能要检查是否是数据由设备发送和获取它们
你可以用适当的SerialPort方法轻松重构这段代码,实际上有更好更简洁的方法来检查串口上是否有数据可用。
而不是“我正在检查端口上有多少字节,如果有什么,然后我等待300毫秒,然后再次相同的事情。“这很可悲地结束于
”所以是2倍300毫秒= 600毫秒,或只是一次(取决于是否有第一次“,或者什么也没有(取决于你通过这个用户界面进行通信的设备)因为Thread.Sleep会阻止用户界面......)。“
首先让我们考虑一段时间,您试图保持尽可能多的相同的代码库,为什么不等待600ms?
或者为什么不只是使用ReadTimeout属性和捕捉超时异常,不是那么干净,但至少在可读性方面更好,而且您直接获取字符串而不是使用一些Convert.ToChar()调用...
我感觉代码已经从C或C++(或者至少是背后的原理)移植到了主要是嵌入式软件背景的人身上。
无论如何,回到可用字节检查的数量,我的意思是除非串行端口数据在另一个线程/ BackgroundWorker/Task处理程序中刷新,否则我没有看到任何检查它的两个原因,特别是以它的方式编码。
为了让它更快?不是真的,如果串行端口上实际存在数据,则会有额外延迟。这对我来说没有多大意义。
使您的代码片段稍微好一点的另一种方法是使用ReadExisting()进行轮询。
否则,您也可以考虑使用SerialPort BaseStream的异步方法。
总而言之,如果不访问代码库的其余部分,即上下文,很难说。
如果您有更多关于目标/协议的信息,它可以提供一些关于如何做的提示。否则,我可以说这似乎是编码不好,再一次,脱节。
我甚至把汉斯提到的关于用户界面响应的问题翻了一番,因为我真的希望你的代码片段在一个不是用户界面的线程中运行(尽管你在帖子中提到用户界面正在轮询我仍然希望该片段是为另一名工人)。
如果这确实是UI线程,那么每次有Thread.Sleep调用都会阻止它,这会导致UI不能真正响应用户交互,并且可能会给最终用户带来一些挫折感。
可能还需要订阅DataReceived事件并执行处理程序所需的操作(例如,使用缓冲区和比较值等)。
请注意mono还没有实现这个事件的触发器,但是如果你正在运行一个简单的MS .NET实现,这是完美的没有多线程的麻烦。
简而言之:
- 检查哪个线程(S)为被照顾您的片断和心灵有关的UI响应
- 如果是UI,然后通过使用另一个线程线程,BackgroundWorker(线程池)或任务。
- 流异步方法,以避免UI线程同步的
- 尝试的麻烦,看目标是否真的值得双300毫秒线程睡眠方法调用
- ,您可以直接获取字符串代替如果后者检查正在使用以执行操作而不是自己收集字节(如果所选编码可以满足您的需要),则可以采集数据。
流异步方法(例如'port.BaseStream.ReadAsync')不使用另一个线程....这是件好事。您不必担心从多个线程同步对数据结构的访问,或者在线程之间编组UI。每当事件处理程序返回或调用“await”时,只需将数据结构保持一致即可。 –
@BenVoigt http://referencesource.microsoft.com/#mscorlib/system/io/stream.cs,e224b4bec8748849 async/await正在使用Task,所以Threadpool。因此它可以在另一个线程上运行,但不一定。 如果你认为我错了,随意解释一下。 同意特别是当它与用户界面相关时。 – Ehouarn
任务对象默认在当前上下文中运行,在UI应用程序中,默认上下文是UI消息分派器。没有使用额外的线程。现在,您可以选择将任务强制为工作线程,但这对于I/O尤其是串行I/O来说很愚蠢。工作线程仅对CPU绑定操作有利。 –