將SerialPort 封裝在內部,改善直接使用SerialPort Class 的問題。
改善後的 JgeComport Class :
using System;using System.Collections.Generic;using System.ComponentModel;using System.Windows.Forms;using System.Linq;using System.Text;using System.IO.Ports;using System.IO;using System.Threading;using System.Diagnostics;namespace SBM75e_4{ /// <summary> /// 事件委派宣告 /// </summary>public delegate void jgecomEventHandler(object sender, jgecomEventArgs e);
/// <summary> /// 定義專用事件參數類別 /// </summary>public class jgecomEventArgs : EventArgs
{private string mComName;
private Stream mMSG = new MemoryStream();
//Byte[] mMSG = new Byte[1024]; //public jgecomEventArgs(byte[] msg, string commName)public jgecomEventArgs(Stream msg, string commName)
{MSG = msg;
NAME = commName;
}
public string NAME
{ get { return mComName; }private set { mComName = value; }
}
//public byte[] MSG public Stream MSG { get { return mMSG; }private set { mMSG = value; }
}
}
// Invok 跳板的委派宣告delegate void onInvok(Stream buffer);
class JgeComport { #region 靜態公用函式 /// <summary> /// 將 Byte陣列 轉為 Stream /// </summary> /// <returns>Stream</returns>public static Stream BytesToStream(byte[] bytes)
{ Stream stream = new MemoryStream(bytes); return stream;}
public static Stream BytesToStream(byte[] bytes, int Length)
{ Stream stream = new MemoryStream(bytes, 0, Length); return stream;}
/// <summary> /// 將 Stream 轉為 Byte陣列 /// </summary>public static byte[] StreamToBytes(Stream stream)
{byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
/*將 stream 指針指向開頭*/stream.Seek(0, SeekOrigin.Begin);
return bytes;}
#endregion /// <summary> /// 委派宣告 /// </summary>private delegate void SetReceived(Stream msg, string ip);
/// <summary> /// 委派欄位 /// </summary> private SetReceived mSetReceivedDlg; /// <summary> /// Received 事件 /// </summary>public event jgecomEventHandler Received;
/// <summary> /// 委派處理函式 /// </summary>private void OnReceivedText(Stream msg, string commName)
{ jgecomEventArgs e = new jgecomEventArgs(msg, commName);if (Received != null) //. 當事件變數不為 null 則執行之
{ Received(this, e);}
}
/// <summary> /// 儲存擁有者 /// </summary>private object mOwner;
//======================================================================== /// <summary> /// SerialPort 物件,設為public 以便直接取用其屬性(偷懶的作法) /// </summary> private SerialPort comport; /// <summary> /// 內部使用變數 /// </summary>private Boolean mReceiving; // 能讓DoReceive方法內的While迴圈停止
private Thread mRxThread; // Thread型別的變數 mRxThread,則是為了產生執行緒所宣告
/// <summary> /// 建構式 /// </summary>public JgeComport(object Owner)
{mOwner = Owner;
mSetReceivedDlg = OnReceivedText;/*設定委派處理函式*/ comport = new SerialPort();}
/// <summary> /// Connect 方法-1 /// </summary>public void Connect(string portName,int baudRate,Parity parity,int dataBits,StopBits stopBits)
{comport.PortName = portName;
comport.BaudRate=baudRate;
comport.Parity=parity;
comport.DataBits=dataBits;
comport.StopBits = stopBits;
Connect();
}
/// <summary> /// Connect 方法-2 /// </summary>public void Connect()
{ if (!comport.IsOpen) {comport.Open();
// 產生執行緒來執行自訂的DoReceive方法 mReceiving = true; mRxThread = new Thread(DoReceive); //mRxThread = new Thread(DoReceiveEx); mRxThread.IsBackground = true;mRxThread.Start();
}
}
#region 以執行緒處裡Rx事件 /// <summary> /// 以執行緒處裡Rx事件 /// </summary> /// /* OnReceive 事件跳板 */private void onInvoked(Stream buffer)
{OnReceivedText(buffer, comport.PortName.ToString());
}
/* Rx 執行緒 */private void DoReceive()
{ Byte[] buffer = new Byte[1024]; while (mReceiving) { if (comport.BytesToRead > 0) { Thread.Sleep(312); // Sleep 一段時間,用以讀取個多數據(該處可加入判斷式,進行更多的條件讀取)Int32 length = comport.Read(buffer, 0, buffer.Length);
Array.Resize(ref buffer, length); onInvok d = new onInvok(onInvoked);/* Invoke */((System.Windows.Forms.Form)mOwner).Invoke(d, new Object[] { BytesToStream(buffer) });
Array.Resize(ref buffer, 1024);}
Thread.Sleep(16);
}
}
#endregion #region SerialPort 對應之屬性 /// <summary> /// 要使用的連接埠 (例如 COM1) /// </summary>public string PortName
{get
{ return comport.PortName;}
set
{ comport.PortName = value;}
}
/// <summary> /// 傳輸速率: 2400,4800,9600,19200,38400,57600,115200 /// </summary>public int BaudRate
{get
{ return comport.BaudRate;}
set
{ comport.BaudRate = value;}
}
/// <summary> /// System.IO.Ports.Parity /// </summary> public System.IO.Ports.Parity Parity {get
{ return comport.Parity;}
set
{ comport.Parity = value;}
}
/// <summary> /// 資料位元值 /// </summary>public int DataBits
{get
{ return comport.DataBits;}
set
{ comport.DataBits = value;}
}
/// <summary> /// System.IO.Ports.StopBits /// </summary> public System.IO.Ports.StopBits StopBits {get
{ return comport.StopBits;}
set
{ comport.StopBits = value;}
}
/// <summary> /// 取得值,指出 SerialPort 物件的開啟或關閉狀態。 /// </summary> public Boolean IsOpen {get
{ return comport.IsOpen;}
set
{}
}
#endregion /// <summary> /// 關閉連接埠連線 /// </summary>public void Close()
{comport.Close();
}
/// <summary> /// 將指定的字串寫入序列埠 /// </summary>public void Write(string text)
{comport.Write(text);
}
/// <summary> /// 使用緩衝區中的資料,將指定的位元組數目寫入序列埠。 /// </summary>public void Write(byte[] buffer,int offset,int count)
{comport.Write(buffer, offset, count);
}
/// <summary> /// 使用緩衝區中的資料,將指定的字元數目寫入序列埠。 /// </summary>public void Write(char[] buffer,int offset,int count)
{comport.Write(buffer, offset, count);
}
/// <summary> /// 使用Stream中的資料,將指定的字元數目寫入序列埠。 /// </summary>public void Write(Stream buffer, int offset, int count)
{byte[] bytes = new byte[buffer.Length];
comport.Write(bytes, offset, count);
}
/// <summary> /// 將指定字串和 NewLine 值寫入輸出緩衝區 /// </summary>public void WriteLine(String text)
{comport.WriteLine(text);
}
}
}
使用該 Class
JgeComport My232 = new JgeComport(this);
My232.Connect("COM2", 57600, Parity.None, 8, StopBits.One);My232.Received += this.onReceived;string ss = "1234567890";
Byte[] bytes = System.Text.Encoding.ASCII.GetBytes(ss);
Stream stream = new MemoryStream(bytes);My232.Write(ss);
My232.Write(bytes, 0, bytes.Length);
My232.Write(stream, 0, (int)(stream.Length));事件程式
private void onReceived(object sender, jgecomEventArgs e)
{ switch (e.NAME.ToString()) {case "COM2":
Byte[] bytes = new Byte[1024];bytes = JgeComport.StreamToBytes(e.MSG);
string ss = System.Text.Encoding.ASCII.GetString(bytes);textBox1.AppendText(ss + Environment.NewLine);
textBox1.Text += String.Format("{0}{1}", BitConverter.ToString(bytes), Environment.NewLine); //Environment.NewLine => \r\n
label2.Text = bytes.Length.ToString();
break; default: break;}
}
ClassDiagram:
沒有留言:
張貼留言