在main()中为SerialPort添加事件处理程序

时间:2012-01-25 15:48:18

标签: c# event-handling idisposable

我尝试为接收的数据事件订阅事件处理程序。好像我无法指定事件处理函数名称。我不明白为什么
myComPort.DataReceived + = new SerialDataReceivedEventHandler(comPort_DataReceived);给我错误信息。 这是问题所在,希望有人能回答。

a busy cat http://img827.imageshack.us/img827/5904/20120125102247.png

a busy cat http://img444.imageshack.us/img444/3855/20120125102202.png

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);
            }
        }

    }

    }

3 个答案:

答案 0 :(得分:6)

首先,由于方法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; // ... } 参数:

{{1}}

答案 1 :(得分:4)

在您的事件处理程序中,myComPort不在范围内 - 它在main()方法中本地声明。我建议你将com端口处理提取到一个类中,并使myComPort成为该类的成员变量。

另外,您的注释请注意,SerialPort类具有需要使用IDisposable / Using模式处理的托管资源,但您没有使用包装块来访问通信端口。

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

答案 2 :(得分:0)

Tetsujin no Oni的答案是处理范围问题的理想方式。另一种方法也是将myComPort声明为程序的静态成员,例如:

internal List<Byte> portBuffer = new List<Byte>(1024);
private SerialPort myComPort = new SerialPort();

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