Skip to main content
 首页 » 编程设计

c#之处理从串口读取的数据时串口线程锁定

2024年01月26日28shanyou

我有一个事件处理程序,只要在串行端口上接收到数据,它就会被调用,一旦这个事件被调用,我就会处理一个单独的数据字节,直到处理完所有数据。

我的问题是,当我仍在处理第一次调用它时的字节时,我如何确保这个 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 事件类型,这已使相当多的程序员感到困惑。

你不必帮忙。