处理从串行端口读取的数据时,串行端口线程锁定 [英] serial port thread locking while processing data read from serial port
问题描述
我有一个事件处理程序,只要在串行端口上接收到数据,就可以调用该事件处理程序,一旦调用此事件,我就会处理单个数据字节,直到处理完所有数据为止.
我的问题是,如何确保在从第一次调用开始仍处理字节的同时,不再次异步调用此IBSerialPort_DataReceived事件处理程序,即,我想确保ProcessByte方法仅在执行时一次在一个线程上.
void IBSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
while (BytesToRead > 0)
{
ProcessByte((byte)ReadByte());
}
}
首先阅读您使用的库上的文档-事件可以异步引发吗?如果没有,那么您就完成了.
更新:显然,不能同时引发此特定事件,请参阅汉斯·帕桑特的回答.
如果可以的话,一种策略是使用 lock
:
object myLock = new object();
void IBSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
lock(myLock)
{
while (BytesToRead > 0)
{
ProcessByte((byte)ReadByte());
}
}
}
现在请注意,您正在使用锁,如果您在其他位置锁定同一实例,则可能会获得死锁,或者如果您持有相同的锁一段时间,则可能会延迟处理...
此外:通常,文档会告诉您该事件是否可以同时引发,因此您必须处理重新输入的问题,例如System.Threading.Timer
的Tick事件,尽管并非总是如此,例如DatagramSocket
的 MessageReceived 事件.
I have an event handler that gets called anytime data is received on a serial port, once this event is called I process an individual byte of data until all data is processed.
My question is, how do I make sure that this IBSerialPort_DataReceived event handler doesn't get called again asynchronously while I am stilling processing bytes from the first time it was called, ie I want to guarantee the ProcessByte method is only ever executing on one thread at a time.
void IBSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
while (BytesToRead > 0)
{
ProcessByte((byte)ReadByte());
}
}
First read the documentation on the library you are using - can the event be raised asynchronously? If not then you are done.
UPDATE: Apparently this particular event cannot be raised concurrently, see Hans Passant's answer.
If it can, one strategy is to use a lock
:
object myLock = new object();
void IBSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
lock(myLock)
{
while (BytesToRead > 0)
{
ProcessByte((byte)ReadByte());
}
}
}
Take care now that you are using locks, if you lock on the same instance elsewhere you can get dead locks or if you hold the same lock for a while you will hold up processing...
Aside: generally the documentation will tell you if the event can raised concurrently so you will have to deal with re-entry, e.g. System.Threading.Timer
's Tick event, though this is not always the case, e.g. the serverly lacking WinRT documentation on DatagramSocket
's MessageReceived event.
这篇关于处理从串行端口读取的数据时,串行端口线程锁定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!