1. 程式人生 > >串口;線程;委托;事件

串口;線程;委托;事件

tostring 取數 read cep 技術 接收 fault left 代碼

1、構建方法時候,需要用界面來顯示串口接收到的數據,所以我才用了,較為復雜的委托事件線程的方法,把串口接收的模塊並入到我的主工程中;

總結一下串口模塊的設計,

新建一個委托

public delegate void SerialPortEventHandler(Object sender, SerialPortEventArgs e);

新建一個事件 SerialPortEventArgs類,繼承自事件數據的類的基類

public class SerialPortEventArgs : EventArgs
{
public bool isOpend = false;
public Byte[] receivedBytes = null;
}

新建一個ComModel類

   在類中申明事件

    public event SerialPortEventHandler comReceiveDataEvent = null;
    public event SerialPortEventHandler comOpenEvent = null;
    public event SerialPortEventHandler comCloseEvent = null;

    

     private SerialPort sp = new SerialPort();

     private Object thisLock

= new Object();

    在串口控件的事件中,有3個事件

技術分享圖片

當串口接收到數據時,觸發 DataReceived 事件, 單擊產生的方法中加入代碼功能:

  1.假如 sp.BytesToRead <= 0 ,返回。

  2.鎖住線程 lock (thisLock)

  3.讀取數據:  

1                 int len = sp.BytesToRead;
2                 Byte[] data = new Byte[len];
3                 try
4 { 5 sp.Read(data, 0, len); 6 }

  4.new出來自己定義的事件 SerialPortEventArgs

      SerialPortEventArgs args = new SerialPortEventArgs(); 

   事件中傳送的數據

     args.receivedBytes = data;

  5.如果 事件comReceiveDataEvent ,不為空,則用事件......()

    if (comReceiveDataEvent != null)
    {
      comReceiveDataEvent.Invoke(this, args);
    }

     //用事件通知界面

在界面層

  聲明一個接口 IView,並在mainform中引用這個接口 “public partial class FormMain : Form,IView

  public interface IView
  {

  void ComReceiveDataEvent(Object sender, SerialPortEventArgs e);

  }

編寫串口接收事件函數

public void ComReceiveDataEvent(object sender, SerialPortEventArgs e)
{

          //
          // 摘要:
          //     獲取一個值,該值指示調用方在對控件進行方法調用時是否必須調用 Invoke 方法,因為調用方位於創建控件所在的線程以外的線程中。
          //
          // 返回結果:
          //     如果控件的 System.Windows.Forms.Control.Handle 是在與調用線程不同的線程上創建的(說明您必須通過 Invoke 方法對控件進行調用),則為
          //     true;否則為 false。
            if (this.InvokeRequired)
            {
                try
                { //
                  // 摘要:
                  //     在擁有控件的基礎窗口句柄的線程上,用指定的參數列表執行指定委托。
                  //
                  // 參數:
                  //   method:
                  //     一個方法委托,它采用的參數的數量和類型與 args 參數中所包含的相同。
                  //
                  //   args:
                  //     作為指定方法的參數傳遞的對象數組。如果此方法沒有參數,該參數可以是 null。
                  //
                  // 返回結果:
                  //     System.Object,它包含正被調用的委托返回值;如果該委托沒有返回值,則為 null。
                    Invoke(new Action<Object, SerialPortEventArgs>(ComReceiveDataEvent), sender, e);
                }
                catch (System.Exception)
                {
                    //disable form destroy exception
                }
                return;
            }
            if (true) //字符串display as string
            {
                receivetbx.AppendText(Encoding.Default.GetString(e.receivedBytes));
                receiveBytesCount += e.receivedBytes.Length;
                acceptStatusLabel.Text = "Received: " + receiveBytesCount.ToString();
            }

}

串口;線程;委托;事件