我尝试将事件处理程序订阅到数据接收事件。似乎我无法指定事件处理程序函数名称。我不明白为什么
myComPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
给我错误信息。
问题就在这里,希望大家能解答。
namespace serialport
{
public class Program
{
internal List<Byte> portBuffer = new List<Byte>(1024);
static void Main()
{
//1. find available COM port
string[] nameArray = null;
string myComPortName = null;
nameArray = SerialPort.GetPortNames();
if (nameArray.GetUpperBound(0) >= 0)
{
myComPortName = nameArray[0];
}
else
{
Console.WriteLine("Error");
return;
}
//2. create a serialport object
// the port object is closed automatically by use using()
SerialPort myComPort = new SerialPort();
myComPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
myComPort.PortName = myComPortName;
//the default paramit are 9600,no parity,one stop bit, and no flow control
//3.open the port
try
{
myComPort.Open();
}
catch (UnauthorizedAccessException ex)
{
MessageBox.Show(ex.Message);
}
//Add timeout, p161
//reading Bytes
byte[] byteBuffer = new byte[10];
Int32 count;
Int32 numberOfReceivedBytes;
myComPort.Read(byteBuffer, 0, 9);
for (count = 0; count <= 3; count++)
{
Console.WriteLine(byteBuffer[count].ToString());
}
}
//The event handler should be static??
void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int numberOfBytesToRead;
numberOfBytesToRead = myComPort.BytesToRead;
byte[] newReceivedData = new byte[numberOfBytesToRead];
myComPort.Read(newReceivedData, 0, numberOfBytesToRead);
portBuffer.AddRange(newReceivedData);
ProcessData();
}
private void ProcessData()
{
//when 8 bytes have arrived, display then and remove them from the buffer
int count;
int numberOfBytesToRead = 8;
if (portBuffer.Count >= numberOfBytesToRead)
{
for (count = 0; count < numberOfBytesToRead; count++)
{
Console.WriteLine((char)(portBuffer[count]));
}
portBuffer.RemoveRange(0, numberOfBytesToRead);
}
}
}
}
首先,由于方法
Main
是静态的,因此只能调用同一个类中的其他静态方法。事实上,comPort_DataReceived
被声明为实例方法,以下代码应该修复事件处理程序的分配:
static void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// ...
}
其次,由于
myComPort
是在Main
中定义的,所以它在comPort_DataReceived
中是不可见的。您有两种选择:要么将 myComPort
声明为类的静态成员,要么使用事件处理程序的 sender
参数:
static void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = (SerialPort)sender;
// ...
}
在您的事件处理程序中,myComPort 不在范围内 - 它是在您的 main() 方法中本地声明的。我建议您将 com 端口处理提取到一个类中,并使 myComPort 成为该类的成员变量。
此外,您的评论指出 SerialPort 类有一个托管资源,需要使用 IDisposable / using 模式来处理该资源,但您没有使用块来包装对通信端口的访问。
最后,您添加为事件处理程序的方法作为实例成员而不是静态成员存在;要从 main() 方法的静态范围访问它,您需要从类的实例中获取它或使该方法静态。
Tetsujin no Oni 的答案是处理范围问题的理想方法。另一种可行的方法是将
myComPort
声明为程序的静态成员,例如:
internal List<Byte> portBuffer = new List<Byte>(1024);
private SerialPort myComPort = new SerialPort();
然后只需从
myComPort
方法中删除 main
声明即可。