2012-01-25 13 views
5

Intento suscribir un controlador de eventos al evento de datos recibidos. Parece que no puedo especificar el nombre de la función del manejador de eventos. No entiendo por qué
myComPort.DataReceived + = new SerialDataReceivedEventHandler (comPort_DataReceived); me está dando un mensaje de error. Aquí está el problema, espero que cualquiera pueda responderlo.Adición de controlador de eventos en main() para SerialPort

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

    } 

    } 

Respuesta

4

En el controlador de eventos, myComPort no es de alcance - es declarado localmente en su método main(). Sugeriría que extraigas el manejo del puerto de comunicación en una clase y que myComPort sea una variable miembro de esa clase.

Además, sus comentarios señalan que la clase SerialPort tiene un recurso gestionado que debe eliminar usando el patrón IDisposable/Using, pero no tiene un bloque que lo envuelve.

Por último, el método que está agregando como el controlador de eventos existe como un miembro de instancia en lugar de como un miembro estático; para acceder desde el alcance estático del método main(), necesita agarrarlo de una instancia de la clase o hacer que el método sea estático.

6

En primer lugar, como el método Main es estático, solo puede llamar a otros métodos estáticos de la misma clase. Como es, comPort_DataReceived se declara como un método de instancia, el siguiente código debe fijar la asignación del controlador de eventos:

static void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    // ... 
} 

segundo lugar, puesto myComPort se define en Main, no será visible en comPort_DataReceived. Usted tiene dos opciones: o bien declarar myComPort como un miembro estático de la clase, o utilizar el argumento sender del controlador de eventos:

respuesta
static void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    SerialPort port = (SerialPort)sender; 
    // ... 
} 
+4

+1 para enviar el remitente. Algunas refactorizaciones pueden ser mejores, pero el principio de enviar el remitente es enormemente útil para saber si hay algún evento. – Chris

+0

refactorización bastante importante es definitivamente necesario si desea un programa de C# adecuado que siga los principios de OOP. También omití el hecho de que otros métodos y variables de instancia seguirán siendo un problema, traté de mantener la respuesta pedagógica en lugar de solo proporcionar el código que hubiera utilizado yo mismo, por lo que es necesario investigar un poco más;) – madd0

+0

Así declarar un método estático lo hace pertenecer a un tipo más bien a una instancia, ¿verdad? si es así, ¿deberíamos declarar siempre que el controlador de eventos es estático? Supongo que si puse mycomport como miembro de la clase, debería ser visible para todos los métodos, ¿verdad? – fiftyplus

0

Tetsujin no Oni 's es la forma ideal para manejar su problema con el alcance. Otro enfoque que también funciona es declarar myComPort como un miembro estático de su programa, por ejemplo .:

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

Después, simplemente retire la declaración myComPort de su método main.

+0

Pero oh, los problemas de enhebrado que podrías crear al tener ese hábito. –

+0

@TetsujinnoOni Por supuesto, no estaba sugiriendo que OP lo convirtiera en un hábito :) He escrito suficientes aplicaciones basadas en socket para saber lo doloroso que es tener puntos muertos en un solo hilo. –

+0

Quería asegurarme de que había conciencia del problema, ya que el OP había mencionado que era nuevo en C#. –

Cuestiones relacionadas