包含具有相同 SerialDataReceivedEventHandler 的 SerialPort 的多个对象
Multiple objects containing SerialPort with same SerialDataReceivedEventHandler
我有两个对象(属于同一个 class),每个对象都包含一个 SerialPort
对象。 class 有一个处理 SerialPort.DataReceived
事件的方法并被两个 SerialPort
对象使用。
当我在单独的应用程序中实例化每个对象时,每个端口都会按预期单独处理其 DataReceived
事件。
当我在同一应用程序中实例化 COM_Front_End
class 的两个实例并将数据从一个串行端口发送到另一个时,两个端口的 DataReceived
事件处理程序都会触发。简而言之,我将其称为 "cross-talk".
我的 class 结构看起来像这样:
public class COM_Front_End
{
private SerialPort_custom port;
private LockObject;
public COM_Front_End(string PortName, string BaudRate)
{
// Other code
port = new SerialPort_custom(PortName, BaudRate, new SerialDataReceivedEventHandler(SerialDataReceived));
port.Open();
}
private void SerialDataReceived(object sender, SerialDataReceivedEventArgs e)
{
//lock (LockObject) // A lock is not needed here. Only one SerialDataReceived event can fire at a time
//{
SerialPort port;
try
{
port = sender as SerialPort;
if (port != null)
{
byte[] buffer = new byte[port.BytesToRead];
int bytesRead = port.Read(buffer, 0, buffer.Length);
foreach (byte inByte in buffer)
{
// Byte processing code
}
}
}
catch (Exception ex)
{
// Exception handling code
}
//}
}
}
包含实际 SerialPort
class 的 class 看起来像:
public class SerialPort_custom : SerialPort
{
public SerialPort_custom(string PortName, int BaudRate, SerialDataReceivedEventHandler DataReceivedHandler)
{
this.PortName = PortName;
this.BaudRate = BaudRate;
this.Parity = System.IO.Ports.Parity.None;
this.DataBits = 8;
this.StopBits = System.IO.Ports.StopBits.One;
this.Handshake = System.IO.Ports.Handshake.None;
this.RtsEnable = true;
this.DtrEnable = true;
this.DiscardNull = false;
this.Encoding = Encoding.ASCII;
this.DataReceived += DataReceivedHandler;
}
// Other methods
}
我在同一应用程序中有两个 COM_Front_End
class 实例。每当一个实例接收到数据时,两个对象的 SerialDataReceived
方法都会触发。
为什么在同一个应用程序中实例化两个串行端口时,DataReceived
事件处理程序会触发它们?此外,如何确保此 class 的多次实例化不会导致 "cross-talk"?
我找到了问题的根本原因:
COM_Front_End
所在的项目有两个静态classes。其中一个 classes 是接收缓冲区,另一个是传输缓冲区。更改这些 classes 使它们不是静态的解决了我的问题。在每个 COM_Front_End
对象中都有一个轮询接收缓冲区的任务。因为它们都使用相同的静态 class,它们都从这个缓冲区中提取数据,这就解释了为什么
一个。 SerialDataReceived
两个对象都被触发了。
乙。每个收到的数据是 mangled/partial.
TL;DR:包含静态对象的非静态对象将产生共享资源,无论是否有意。
如果我的解释有错误或不完整,请指正。
我有两个对象(属于同一个 class),每个对象都包含一个 SerialPort
对象。 class 有一个处理 SerialPort.DataReceived
事件的方法并被两个 SerialPort
对象使用。
当我在单独的应用程序中实例化每个对象时,每个端口都会按预期单独处理其 DataReceived
事件。
当我在同一应用程序中实例化 COM_Front_End
class 的两个实例并将数据从一个串行端口发送到另一个时,两个端口的 DataReceived
事件处理程序都会触发。简而言之,我将其称为 "cross-talk".
我的 class 结构看起来像这样:
public class COM_Front_End
{
private SerialPort_custom port;
private LockObject;
public COM_Front_End(string PortName, string BaudRate)
{
// Other code
port = new SerialPort_custom(PortName, BaudRate, new SerialDataReceivedEventHandler(SerialDataReceived));
port.Open();
}
private void SerialDataReceived(object sender, SerialDataReceivedEventArgs e)
{
//lock (LockObject) // A lock is not needed here. Only one SerialDataReceived event can fire at a time
//{
SerialPort port;
try
{
port = sender as SerialPort;
if (port != null)
{
byte[] buffer = new byte[port.BytesToRead];
int bytesRead = port.Read(buffer, 0, buffer.Length);
foreach (byte inByte in buffer)
{
// Byte processing code
}
}
}
catch (Exception ex)
{
// Exception handling code
}
//}
}
}
包含实际 SerialPort
class 的 class 看起来像:
public class SerialPort_custom : SerialPort
{
public SerialPort_custom(string PortName, int BaudRate, SerialDataReceivedEventHandler DataReceivedHandler)
{
this.PortName = PortName;
this.BaudRate = BaudRate;
this.Parity = System.IO.Ports.Parity.None;
this.DataBits = 8;
this.StopBits = System.IO.Ports.StopBits.One;
this.Handshake = System.IO.Ports.Handshake.None;
this.RtsEnable = true;
this.DtrEnable = true;
this.DiscardNull = false;
this.Encoding = Encoding.ASCII;
this.DataReceived += DataReceivedHandler;
}
// Other methods
}
我在同一应用程序中有两个 COM_Front_End
class 实例。每当一个实例接收到数据时,两个对象的 SerialDataReceived
方法都会触发。
为什么在同一个应用程序中实例化两个串行端口时,DataReceived
事件处理程序会触发它们?此外,如何确保此 class 的多次实例化不会导致 "cross-talk"?
我找到了问题的根本原因:
COM_Front_End
所在的项目有两个静态classes。其中一个 classes 是接收缓冲区,另一个是传输缓冲区。更改这些 classes 使它们不是静态的解决了我的问题。在每个 COM_Front_End
对象中都有一个轮询接收缓冲区的任务。因为它们都使用相同的静态 class,它们都从这个缓冲区中提取数据,这就解释了为什么
一个。 SerialDataReceived
两个对象都被触发了。
乙。每个收到的数据是 mangled/partial.
TL;DR:包含静态对象的非静态对象将产生共享资源,无论是否有意。
如果我的解释有错误或不完整,请指正。