2012-01-25 7 views
5

Próbuję zasubskrybować procedurę obsługi zdarzeń do zdarzenia odebranego. Wygląda na to, że nie mogę podać nazwy funkcji modułu obsługi zdarzeń. Nie rozumiem, dlaczego
myComPort.DataReceived + = new SerialDataReceivedEventHandler (comPort_DataReceived); daje mi komunikat o błędzie. Oto problem, mam nadzieję, że ktoś może na nie odpowiedzieć.Dodawanie obsługi zdarzeń w głównej() dla 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); 
      } 
     } 

    } 

    } 

Odpowiedz

4

W swojej obsługi zdarzeń, myComPort nie jest w zakresie - to zadeklarowana lokalnie w swoim głównym sposobem(). Sugeruję, aby wyodrębnić obsługę portu COM na klasę i uczynić myComPort członową zmienną tej klasy.

Ponadto, twoje uwagi zauważają, że klasa SerialPort ma zarządzany zasób, który musi usunąć przy użyciu wzorca IDisposable/Using, ale nie masz blokującego dostępu do portu komunikacyjnego.

Ostatnia metoda dodawana jako obsługa zdarzeń istnieje jako element instancji, a nie jako element statyczny; aby uzyskać do niego dostęp z zakresu statycznego metody main(), musisz albo pobrać ją z instancji klasy, albo uczynić metodę statyczną.

6

Po pierwsze, ponieważ metoda Main jest statyczna, można wywoływać tylko inne statyczne metody w tej samej klasie. Jak to jest, comPort_DataReceived jest zadeklarowana jako metody instancji, następujący kod powinien rozwiązać zadanie z obsługi zdarzenia:

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

drugie, ponieważ myComPort jest zdefiniowana w Main, to nie będzie widoczne w comPort_DataReceived. Masz dwie możliwości: albo deklarują myComPort jako statyczne członka klasy lub użyj sender argument obsługi zdarzenia:

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

+1 za odesłanie nadawcy. Niektóre refaktoryzacja może być lepsza, ale zasada rzucania nadawcy jest bardzo przydatna, aby wiedzieć o każdym użyciu zdarzenia. – Chris

+0

dość ważne refaktoryzacja jest definitywnie konieczna, jeśli chcesz mieć odpowiedni program C# zgodny z zasadami OOP. Pominąłem także fakt, że inne metody i zmienne instancji nadal będą stanowić problem, starałem się zachować odpowiedź pedagogiczną zamiast dostarczania kodu, który sam bym użył, więc potrzebne są dalsze badania;) – madd0

+0

Deklaracja metoda static sprawia, że ​​należy do typu raczej do instancji, prawda? jeśli tak, czy zawsze powinniśmy zadeklarować obsługę zdarzeń jako statyczną? Zgaduję, że jeśli umieściłbym mycomport jako członka klasy, powinien on być widoczny dla wszystkich metod, prawda? – fiftyplus

0

Tetsujin no Oni „s odpowiedź jest idealnym sposobem, aby obsłużyć problem z zakresu. Innym rozwiązaniem, które również działa to zadeklarować myComPort jako statyczny członka swojego programu, np .:

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

Wtedy po prostu usunąć deklarację myComPort od wybranej metody main.

+0

Ale o problemach z wątkami, które możesz stworzyć, wchodząc w ten nawyk. –

+0

@TetsujinnoOni Oczywiście - nie sugerowałem, że OP to nawyk;) Napisałem wystarczająco dużo aplikacji opartych na gniazdach, aby wiedzieć, jak bolesne jest mieć zakleszczenia w jednym wątku. –

+0

Chciałem mieć pewność, że istnieje świadomość problemu, ponieważ PO wspomniał, że był nowy w C#. –