C# 包含具有相同SerialDataReceiveDevenHandler的SerialPort的多个对象
我有两个对象(属于同一类),每个对象都包含一个C# 包含具有相同SerialDataReceiveDevenHandler的SerialPort的多个对象,c#,event-handling,serial-port,C#,Event Handling,Serial Port,我有两个对象(属于同一类),每个对象都包含一个SerialPort对象。该类有一个处理SerialPort.DataReceived事件的方法,并由SerialPort对象使用 当我在一个单独的应用程序中实例化每个对象时,每个端口都会按预期分别处理其DataReceived事件 当我在同一个应用程序中实例化COM\u Front\u End类的两个实例并将数据从一个串行端口发送到另一个串行端口时,两个端口的DataReceived事件处理程序都会启动。简而言之,我称之为“相声” 我的班级结构如下
SerialPort
对象。该类有一个处理SerialPort.DataReceived
事件的方法,并由SerialPort
对象使用
当我在一个单独的应用程序中实例化每个对象时,每个端口都会按预期分别处理其DataReceived
事件
当我在同一个应用程序中实例化COM\u Front\u End
类的两个实例并将数据从一个串行端口发送到另一个串行端口时,两个端口的DataReceived
事件处理程序都会启动。简而言之,我称之为“相声”
我的班级结构如下所示:
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
类的类如下所示:
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\u Front\u End
类的实例。每当一个实例接收数据时,两个对象的SerialDataReceived
方法都会触发
当两个串行端口在同一应用程序中实例化时,为什么会为它们触发
DataReceived
事件处理程序?此外,如何确保该类的多个实例化不会导致“串扰”我已经找到了问题的根本原因:
COM\u前端所在的项目有两个静态类。其中一类是接收缓冲区,另一类是发送缓冲区。更改这些类以使它们不是静态的解决了我的问题。在每个COM\u前端
对象中都有一个轮询接收缓冲区的任务。因为它们都使用相同的静态类,所以它们都从这个缓冲区中提取,这就解释了为什么
A.已接收两个已激发对象的SerialDataReceived
B.每个接收到的数据被损坏/部分损坏
TL;DR:包含静态对象的非静态对象将产生共享资源,无论是否有意
如果我的解释有错误或不完整,请纠正我。主持人:我想不出更好的标题来回答我的问题。欢迎对标题进行任何调整,使其更加简洁。在问题的第一部分,您说您正在将数据从一个端口发送到另一个端口,因此将两者连接在一起。您是否检查过,如果您将串行数据从单独的源(另一台PC)发送到应用程序上的单个端口,会发生什么情况?这两个事件处理程序是否仍然启动?另外,如果在两个端口之间发送数据会导致数据同时到达两个端口,您是否使用其他应用程序进行了检查(在我使用串行端口的时候,我使用了HyperTerminal和其他应用程序,如PCAnywhere,但不确定这些天有什么可用)。我将其中一个串行端口连接到外部串行源,但未发现两个串行端口都有数据接收事件。很高兴您发现了问题。一个问题,为什么要锁定处理程序?一个串行端口一次只能处理它的一个事件。@dbasnett:它实际上不应该在那里。这是解决我遇到的上述问题的最后努力。我编辑了问题陈述以反映这一点。谢谢