1. 程式人生 > >C# 串口接收數據中serialPort.close()死鎖

C# 串口接收數據中serialPort.close()死鎖

字符 fig ext 判斷 com end 直接 except 之間

最近在做一個有關高鐵模擬倉顯示系統的客戶端程序,在這個程序中要運用串口serialPort傳輸數據,因為每次接收數據結束後要更新UI界面,所以就用到了的Invoke,將更新UI的程序代碼封裝到一個方法中,然後通過Incoke調用,程序跑起來沒有任何問題,但是當你執行serialPort.close()是程序就會發生死鎖,整個程序卡在那裏動都動不了。上網查了很多資料,有各種這樣的說法,有的說定義一個接收數據的標誌,如果在執行關閉程序是進行判斷,如果數據接收完了就關閉串口,沒有的話繼續執行,但是經過親自測試並沒有什麽卵用,最後自己研究invoke的時候發現還有Begininvoke,同時也發現了他們之間的不同,begininvoke用於後臺更新UI數據無需等待的情況,而invoke用於後臺更新UI數據無需要等待的情況,弄明白這兩個之間的不同之後才明白原來執行serialPort.close()發生死鎖的原因就是invoke在作祟,改成begininvoke就不會出現思索問題。直接上代碼:

SerialPort serialPort1 = new SerialPort(configComString, 115200, Parity.None, 8, StopBits.One); //初始化串口設置
//定義委托
public delegate void Displaydelegate(byte[] InputBuf);
Byte[] OutputBuf = new Byte[8];
public Displaydelegate disp_delegate;

//接收數據委托
disp_delegate = new Displaydelegate(DispUI);
serialPort1.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);

//串口讀取數據處理函數
public void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
{

Byte[] InputBuf = new Byte[8];

try
{
serialPort1.Read(InputBuf, 0, serialPort1.BytesToRead); //讀取緩沖區的數據直到“}”即0x7D為結束符
System.Threading.Thread.Sleep(100);
this.BeginInvoke(disp_delegate, InputBuf);//disp_delegate是定義的委托事件,在委托事件中調用修改UI的程序
}
catch (TimeoutException ex) //超時處理
{
MessageBox.Show(ex.ToString());
}

}

//更新UI界面
public void DispUI(byte[] InputBuf)
{

string str = System.Text.Encoding.Default.GetString(InputBuf);
// Console.WriteLine(str);
string strW = str.Substring(0, 2);//截取str的子串,從index=0開始截取長度為2的字符串
int OutStrW = int.Parse(strW);
string strS = str.Substring(2, 2);//截取str的子串,從index=2開始截取長度為2的字符串
int OutStrS = int.Parse(strS);
OutstrWen = (OutStrW - 4).ToString();
textBox8.Text = strW;
textBox9.Text = (OutStrW - 4).ToString();
textBox10.Text = strS;
textBox11.Text = (OutStrS - 10).ToString();
}

C# 串口接收數據中serialPort.close()死鎖