Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在SerialPort的main()中添加事件处理程序_C#_Event Handling_Idisposable - Fatal编程技术网

C# 在SerialPort的main()中添加事件处理程序

C# 在SerialPort的main()中添加事件处理程序,c#,event-handling,idisposable,C#,Event Handling,Idisposable,我尝试将事件处理程序订阅到接收到的数据事件。似乎我无法指定事件处理程序函数名。我不明白为什么 myImport.DataReceived+=新的SerialDataReceivedEventHandler(comPort\u DataReceived);正在给我错误消息。 这里有个问题,希望任何人都能回答 名称空间串行端口 { 公共课程 { 内部列表端口缓冲区=新列表(1024); 静态void Main() { //1.查找可用的COM端口 字符串[]nameArray=null; 字符串

我尝试将事件处理程序订阅到接收到的数据事件。似乎我无法指定事件处理程序函数名。我不明白为什么
myImport.DataReceived+=新的SerialDataReceivedEventHandler(comPort\u DataReceived);正在给我错误消息。 这里有个问题,希望任何人都能回答

名称空间串行端口
{
公共课程
{
内部列表端口缓冲区=新列表(1024);
静态void Main()
{
//1.查找可用的COM端口
字符串[]nameArray=null;
字符串myComPortName=null;
nameArray=SerialPort.GetPortNames();
如果(nameArray.GetUpperBound(0)>=0)
{
myComPortName=nameArray[0];
}
其他的
{
控制台写入线(“错误”);
返回;
}
//2.创建一个serialport对象
//使用()自动关闭端口对象
SerialPort myImport=新的SerialPort();
myImport.DataReceived+=新的SerialDataReceivedEventHandler(comPort\u DataReceived);
myImport.PortName=myImportName;
//默认参数为9600,无奇偶校验,一个停止位,无流量控制
//3.打开端口
尝试
{
myImport.Open();
}
捕获(未经授权的访问例外)
{
MessageBox.Show(例如Message);
}
//添加超时,p161
//读取字节
字节[]byteBuffer=新字节[10];
Int32计数;
Int32接收字节数;
myimport.Read(byteBuffer,0,9);
for(count=0;count=numberOfBytesToRead)
{
for(count=0;count
在事件处理程序中,myImport不在范围内-它在main()方法中本地声明。我建议您将com端口处理提取到一个类中,并使MyImport成为该类的成员变量

另外,您的注释注意到SerialPort类有一个托管资源,它需要使用IDisposable/using模式来处理该资源,但是您没有一个using块来包装对comm端口的访问


最后,作为事件处理程序添加的方法作为实例成员而不是静态成员存在;要从main()方法的静态作用域访问它,您需要从类的实例中获取它,或者使该方法成为静态的。

首先,由于method
main
是静态的,因此您只能调用同一类中的其他静态方法。实际上,
comPort\u DataReceived
被声明为实例方法,下面的代码应该修复事件处理程序的分配:

static void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
   // ...
}
static void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort port = (SerialPort)sender;
    // ...
}
其次,由于
myComPort
是在
Main
中定义的,因此它在
comPort\u DataReceived
中不可见。您有两种选择:要么将
myimport
声明为类的静态成员,要么使用事件处理程序的
sender
参数:

static void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
   // ...
}
static void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort port = (SerialPort)sender;
    // ...
}
的答案是用范围处理问题的理想方法。另一种同样有效的方法是将MyImport声明为程序的静态成员,例如:

internal List<Byte> portBuffer = new List<Byte>(1024);
private SerialPort myComPort = new SerialPort();
内部列表portBuffer=新列表(1024);
私有SerialPort myImport=新SerialPort();

然后,只需从
main
方法中删除
myimport
声明。

+1即可强制转换发送方。有些重构可能更好,但是对于任何事件的使用,强制转换发送者的原则都非常有用。如果你想要一个遵循OOP原则的合适的C#程序,重构是非常重要的。我还忽略了一个事实,即其他实例方法和变量仍然是一个问题,我试图将答案保持为教学性的,而不是仅仅提供我自己会使用的代码,因此有必要进行进一步的研究;)所以声明一个静态方法会使它属于一个类型而不是一个实例,对吗?如果是这样,我们是否应该始终将事件处理程序声明为静态的?我想如果我将myImport作为类的一个成员,那么它应该对所有方法都可见,对吗?您的第一个短语是正确的。至于其余的,您将快速编写包含多个类的程序。您可能正在创建这些类的实例,因此需要更多的实例方法、属性和字段。你在这个问题上的例子很特别,因为所有事情都发生在程序的启动类和方法中,这恰好是静态的,但很少发生。嗨,madd0,在我使MyImport成为该类的成员后,旧问题得到了解决,但是,MyImport对主程序不可见,这里发生了什么?但是,哦,如果你养成了这个习惯,你可能会产生线程问题。@Tetsujinnoni当然-我不是建议OP养成习惯:)我已经编写了足够多的基于套接字的应用程序,知道在单个线程上出现死锁是多么痛苦。我想确保人们意识到了这个问题,因为OP提到了C#是新来的。