2012-01-25 17 views
5

के लिए मुख्य() में ईवेंट हैंडलर जोड़ना मैं डेटा प्राप्त ईवेंट में ईवेंट हैंडलर की सदस्यता लेने का प्रयास करता हूं। ऐसा लगता है कि मैं इवेंट हैंडलर फ़ंक्शन नाम निर्दिष्ट नहीं कर सकता। मुझे समझ में नहीं आता क्यों
myComPort.DataReceived + = नया 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); 
      } 
     } 

    } 

    } 

उत्तर

4

अपने ईवेंट हैंडलर में, myComPort दायरे में नहीं है - यह अपने main() प्रणाली में स्थानीय रूप से घोषित कर रहा है। मैं सुझाव दूंगा कि आप कॉम पोर्ट हैंडलिंग को कक्षा में निकाल दें और MyComPort को उस वर्ग का सदस्य चर बना दें।

इसके अलावा, आपकी टिप्पणियां ध्यान दें कि सीरियलपोर्ट श्रेणी में एक प्रबंधित संसाधन है जिसे इसे IDISposable/उपयोग पैटर्न का उपयोग करने का निपटान करने की आवश्यकता है, लेकिन आपके पास कॉम पोर्ट तक पहुंच को अवरुद्ध करने वाला ब्लॉक उपयोग नहीं है।

आखिरकार, जिस ईवेंट को आप ईवेंट हैंडलर के रूप में जोड़ रहे हैं वह एक स्थिर सदस्य के बजाय एक उदाहरण सदस्य के रूप में मौजूद है; मुख्य() विधि के स्थिर दायरे से इसे एक्सेस करने के लिए, आपको इसे कक्षा के उदाहरण से पकड़ना होगा या विधि को स्थैतिक बनाना होगा।

6

पहला, चूंकि विधि Main स्थिर है, तो आप केवल उसी वर्ग में अन्य स्थिर विधियों को कॉल कर सकते हैं। यह है के रूप में, comPort_DataReceived एक उदाहरण विधि के रूप में घोषित किया जाता है, तो निम्न कोड ईवेंट हैंडलर का काम ठीक करना चाहिए: के बाद से myComPortMain में परिभाषित किया गया है,

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

दूसरा, यह comPort_DataReceived में नहीं दिखाई देंगे।

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

+1। कुछ रिफैक्टरिंग बेहतर हो सकती है लेकिन प्रेषक कास्टिंग करने का सिद्धांत किसी भी घटना के उपयोग के लिए व्यापक रूप से उपयोगी होता है। – Chris

+0

यदि आप एक उचित सी # प्रोग्राम चाहते हैं जो ओओपी सिद्धांतों का पालन करता है तो बहुत महत्वपूर्ण रिफैक्टरिंग निश्चित रूप से जरूरी है। मैंने इस तथ्य को भी छोड़ दिया कि अन्य उदाहरण विधियों और चर अभी भी एक समस्या होगी, मैंने केवल कोड प्रदान करने के बजाय उत्तर शैक्षिक उत्तर रखने की कोशिश की, इसलिए थोड़ा और अनुसंधान आवश्यक है;) – madd0

+0

तो घोषित करें विधि स्थैतिक यह एक उदाहरण के बजाय एक प्रकार से संबंधित है, है ना? यदि हां, तो क्या हमें हमेशा ईवेंट हैंडलर को स्थैतिक घोषित करना चाहिए? मुझे लगता है कि अगर मैं कक्षा के सदस्य के रूप में mycomport डालता हूं, तो यह सभी तरीकों से दिखाना चाहिए, है ना? – fiftyplus

0

Tetsujin no Oni के जवाब गुंजाइश के साथ अपने मुद्दे को संभालने के लिए आदर्श तरीका है: या तो अपने वर्ग के एक सदस्य के रूप में स्थिर myComPort घोषित, या ईवेंट हैंडलर की sender तर्क का उपयोग करें: आपके पास दो विकल्प। एक और दृष्टिकोण भी काम करता है कि आपके कार्यक्रम के एक स्थिर सदस्य, उदा .:

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

इसके बाद अपने main विधि से myComPort घोषणा को दूर के रूप में myComPort घोषित करने के लिए है। प्रेषक कास्टिंग के लिए

+0

लेकिन ओह थ्रेडिंग मुद्दे जो आप उस आदत में शामिल हो सकते हैं। –

+0

@TetsujinnoOni बेशक - मैं यह सुझाव नहीं दे रहा था कि ओपी इसे आदत बनाये :) मैंने पर्याप्त सॉकेट-आधारित ऐप्स लिखे हैं यह जानने के लिए कि एक धागे पर डेडलॉक्स कितना दर्दनाक है। –

+0

मैं यह सुनिश्चित करना चाहता था कि इस मुद्दे पर जागरूकता थी, क्योंकि ओपी ने सी # के लिए नया होने का उल्लेख किया था। –

संबंधित मुद्दे