我有一个事件处理程序,只要在串行端口上接收到数据,它就会被调用,一旦这个事件被调用,我就会处理一个单独的数据字节,直到处理完所有数据。
我的问题是,当我仍在处理第一次调用它时的字节时,我如何确保这个 IBSerialPort_DataReceived 事件处理程序不会被再次异步调用,即我想保证 ProcessByte 方法只执行一次一次在一个线程上。
void IBSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
while (BytesToRead > 0)
{
ProcessByte((byte)ReadByte());
}
}
请您参考如下方法:
这已经在 SerialPort 类中互锁了。如果您的事件处理程序仍在运行,则有一个内部锁可确保 DataReceived 事件不会再次触发。
可以在Reference Source中看到相关代码,我会在这里重现它:
private void CatchReceivedEvents(object src, SerialDataReceivedEventArgs e)
{
SerialDataReceivedEventHandler eventHandler = DataReceived;
SerialStream stream = internalSerialStream;
if ((eventHandler != null) && (stream != null)){
lock (stream) {
// SerialStream might be closed between the time the event runner
// pumped this event and the time the threadpool thread end up
// invoking this event handler. The above lock and IsOpen check
// ensures that we raise the event only when the port is open
bool raiseEvent = false;
try {
raiseEvent = stream.IsOpen && (SerialData.Eof == e.EventType || BytesToRead >= receivedBytesThreshold);
}
catch {
// Ignore and continue. SerialPort might have been closed already!
}
finally {
if (raiseEvent)
eventHandler(this, e); // here, do your reading, etc.
}
}
}
}
注意这段代码中的lock (stream)语句。您还可以看到,除非收到某些内容,否则不会调用您的 DataReceived 事件处理程序。并且您必须注意 SerialData.Eof 事件类型,这已使相当多的程序员感到困惑。
你不必帮忙。
