串口;線程;委托;事件
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
在串口控件的事件中,有3個事件
當串口接收到數據時,觸發 DataReceived 事件, 單擊產生的方法中加入代碼功能:
1.假如 sp.BytesToRead <= 0 ,返回。
2.鎖住線程 lock (thisLock)
3.讀取數據:
1 int len = sp.BytesToRead; 2 Byte[] data = new Byte[len]; 3 try4 { 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(); }
}
串口;線程;委托;事件