2012-01-25 10 views
5

データ受信イベントにイベントハンドラを登録しようとしました。私はイベントハンドラの関数名を指定できないようです。私は理由を理解していません
myComPort.DataReceived + =新しいSerialDataReceivedEventHandler(comPort_DataReceived);私にエラーメッセージを与えています。 ここに問題があります、誰でもそれに答えることができれば幸いです。あなたのイベントハンドラでSerialPortのmain()でイベントハンドラを追加

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

    } 

    } 

答えて

4

、myComPortはスコープではありません - それはあなたのmain()メソッド内でローカルに宣言しています。私はcomポート処理をクラスに抽出し、myComPortをそのクラスのメンバ変数にすることをお勧めします。

また、SerialPortクラスにはIDisposable/Usingパターンを使用して処分する必要のある管理リソースがありますが、commポートへのアクセスをラッピングするusingブロックはありません。

最後に、イベントハンドラとして追加するメソッドは、静的メンバーではなくインスタンスメンバーとして存在します。 main()メソッドの静的スコープからアクセスするには、クラスのインスタンスから取得するか、メソッドを静的にする必要があります。

6

最初に、メソッドMainは静的であるため、同じクラスの他の静的メソッドを呼び出すことができます。それは、comPort_DataReceivedがインスタンスメソッドとして宣言されているように、次のコードは、イベントハンドラの割り当てを修正する必要があります。

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

myComPortMainに定義されているので、それはcomPort_DataReceivedに表示されません。あなたは、2つの選択肢があります。あなたのクラスの静的メンバーとしてmyComPortを宣言するか、イベントハンドラのsender引数を使用するか:

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

+1送信者をキャストします。いくつかのリファクタリングが良いかもしれませんが、送信者をキャストするという原則は、イベントの使用状況を知るのに大いに役立ちます。 – Chris

+0

OOPの原則に従った適切なC#プログラムが必要な場合は、かなり重要なリファクタリングが不可欠です。私はまた、他のインスタンスメソッドと変数が依然として問題であるという事実を省略しました。自分で使っていたコードを提供するのではなく、その答えを教育的に保ちようとしたので、もう少し研究が必要です); – madd0

+0

静的メソッドは、インスタンスではなくタイプに属します。もしそうなら、我々は常にイベントハンドラを静的として宣言すべきですか?私はクラスのメンバとしてmycomportを置く場合、それはすべてのメソッドに表示されるはずですね – fiftyplus

0

Tetsujin no Oniの答えは、スコープを使用して問題を処理するための理想的な方法です。また、作品別のアプローチは、例えば、あなたのプログラムの静的メンバーとしてmyComPortを宣言することです。:

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

その後、単にあなたmain方法からmyComPort宣言を削除してください。

+0

しかし、ああ、あなたはその習慣に入ることを作成することができます問題。 –

+0

@TetsujinnoOniもちろん、私はOPがそれを習慣にすることを示唆していませんでした。私は、スレッドベースでデッドロックを持つのがどれほど苦労しているかを知るために十分なソケットベースのアプリケーションを作成しました。 –

+0

私はOPがC#に新しいことを言及していたので、問題の意識があることを確かめたいと思っていました。 –

関連する問題