2017-03-05 108 views
1

我需要從COM中讀取Form1然後再在Form2中的數據。C#Com端口關閉

什麼將是最好的方法?

Form1讀取COM數據,然後mySerialPort.Close();,並在Form2打開新的連接?
如果這樣,在我的代碼上面我應該在哪裏close呢?

還是不要關閉COM?如果不關閉,我怎樣才能讀取Form2中的數據?

namespace portreader 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 
     private void Form1_Load(object sender, EventArgs e) 
     { 
      SerialPort mySerialPort = new SerialPort(); 
      mySerialPort.PortName = "COM3"; 
      mySerialPort.BaudRate = 9600; 
      mySerialPort.Parity = Parity.None; 
      mySerialPort.StopBits = StopBits.One; 
      mySerialPort.DataBits = 8; 
      mySerialPort.Handshake = Handshake.None; 
      mySerialPort.DataReceived += new SerialDataReceivedEventHandler(mySerialPort_DataReceived); 
      mySerialPort.Open(); 
     } 

     string _buffer; 
     private void mySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) 
     { 
      if (this.InvokeRequired) 
      { 
       // Using this.Invoke causes deadlock when closing serial port, and BeginInvoke is good practice anyway. 
       this.BeginInvoke(new EventHandler<SerialDataReceivedEventArgs>(mySerialPort_DataReceived), new object[] { sender, e }); 
       return; 
      } 
      SerialPort sp = (SerialPort)sender; 
      string data = sp.ReadExisting(); 

      _buffer += data; 
      if (_buffer.Length >= 8) 
      { 
       int chipnumber = Int32.Parse(_buffer, System.Globalization.NumberStyles.HexNumber); 
       Form2 form2 = new Form2(chipnumber); 
       form2.ShowDialog(this); 
       _buffer = null; 
      } 
     } 
    } 
} 
+1

就我個人而言,我會創建一個專門處理應用程序的通信端口通信的類,並且兩種表單都使用該類。 – itsme86

回答

1

你可以簡單地包裹ComPort一類像

public class DataInput 
{ 
    public event Action<string> DataReceived; 

    private readonly SerialPort mySerialPort; 

    public DataInput(string portName) 
    { 
     mySerialPort = new SerialPort(); 
     mySerialPort.PortName = portName; 
     mySerialPort.BaudRate = 9600; 
     mySerialPort.Parity = Parity.None; 
     mySerialPort.StopBits = StopBits.One; 
     mySerialPort.DataBits = 8; 
     mySerialPort.Handshake = Handshake.None; 
     mySerialPort.DataReceived += new SerialDataReceivedEventHandler(mySerialPort_DataReceived); 
     mySerialPort.Open(); 
    } 

    private void mySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     string received = mySerialPort.ReadExisting(); 
     DataReceived?.Invoke(received); 
    } 
} 

現在任何形式的(也是你的軟件的其他組件)可以訂閱DataInput實例的事件DataReceived。所以每個組件都可以按照喜歡的方式處理數據。因此,您只需要創建一個DataReceived實例,並用它在你的報表,如:

public partial class Form1 : Form 
{ 
    private readonly DataInput dataInput; 

    public Form1() 
    { 
     InitializeComponent(); 
     dataInput = new DataInput("COM3"); 
     dataInput.dataReceived += OnDataReceived; 
    } 

    private void OnDataReceived(string Data) 
    { 
     //Do whatever you want with the data 
    } 
} 

現在,你可以通過dataInput你的第二個形式,你可以再次使用dataReceived事件。

+0

我在C#新,想問你是否可以告訴我如何在表單中使用DataReceived,並最終得到它是這樣的:_buffer + = DataReceived; – nordscan

+0

我已經給我的答案添加了一個例子 - 希望這有助於! – Fruchtzwerg

2

您需要創建一個form1和form2都可以使用的類,然後將form1和form2作爲該類的引用。

理想情況下,表單根本沒有任何想法,根本就沒有串口。他們只是使用你的類/服務來提出問題並得到答案,並且封裝在該類中是進入串口並執行查詢的邏輯。

這是軟件的基本設計原理之一,將您的UI與應用程序邏輯分開。

看到另一個相關的帖子我的回答

Serial Port Polling and Data handling