2013-03-13 49 views
0

我目前正在對C#應用程序需要讀取串口。在用戶界面中,有一個開/關按鈕,用戶可以點擊它來開始和停止從串口讀取數據。如果我持續點擊和關閉按鈕。它拋出一個異常 - 訪問COM3被拒絕,甚至說「設備未連接」。任何人都可以提出一個更好的方法來實現能夠解決上述情況的串口功能嗎?下面是我使用的代碼:接受取消事件問題與開閉串口

**// Start reading data from serial port** 
public override void StartReading(string portname) 
{ 
    try 
    { 
     int k = int.Parse(portname.Replace("COM", "")); 
     if (startThread != null) 
     { 
      startThread.Abort(); 
      startThread = null; 
     } 

     startThread = new Thread(new ThreadStart(delegate 
     { 
      isActive = true; 
      try 
      { 
       using (SerialPort sp = new SerialPort(portname)) 
       { 
        if (!isActive) 
        { 
         DisposeBT(sp); 
         return; 
        } 
        sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived); 
        if (!isActive) 
        { 
         DisposeBT(sp); 
         return; 
        } 

        if (!isActive) 
        { 
         DisposeBT(sp); 
         return; 
        } 
        else 
        { 
         Thread.Sleep(6500); 
         try 
         { 
          if (sp != null && !sp.IsOpen) 
          { 
           sp.Open(); 
          } 

         } 
         catch (Exception ex) 
         { 
          Logger.Warn("Failed to open the serial port for HRM once. Try it again."); 
          Logger.Error(ex); 
          ////////////////////// new added below 
          if(sp !=null && sp.IsOpen) 
          { 
           sp.Dispose(); 
          } 
          Thread.Sleep(6500); 
          if (IsPortAvailable(k)) 
          { 
           try 
           { 
            if (sp != null && !sp.IsOpen) 
            { 
             sp.Open(); 
            } 

           } 
           catch (Exception ex1) 
           { 
            ////////////////////// new added below 
            if (sp != null && sp.IsOpen) 
            { 
             sp.Dispose(); 
            } 
            Logger.Warn("Failed to open the serial for HRM twice."); 
            Logger.Error(ex1); 
            // return; 
           } 
          } 
         } 

        } 
        while (true) 
        { 

         if (!isActive) 
         { 
          DisposeBT(sp); 
          break; 
         } 
        } 
        if (!isActive) 
        { 
         DisposeBT(sp); 
         return; 
        } 
        DisposeBT(sp); 
       } 
      } 
      catch (Exception ex) 
      { 
       Logger.Warn("Exception thrown for HRM."); 
       Logger.Error(ex); 
      } 

     })); 
     startThread.IsBackground = true; 
     startThread.Priority = ThreadPriority.Highest; 
     startThread.Start(); 
    } 
    catch (Exception ex) 
    { 
     Logger.Warn("Failed to start reading for HRM02I3A1 bluetooth device."); 
     Logger.Error(ex); 
    } 
} 

// Stop reading data from serial port 
public override void StopReading() 
{ 
    try 
    { 
     isActive = false; 
    } 
    catch { } 
} 

// event handler for the serial port to read data from sp. 
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    if (isActive)// && startThread.IsAlive 
    { 
     SerialPort sp1 = (SerialPort)sender; 
     try 
     { 
      sp1.Read(data, 0, 8); 
      decoder.Decode(data); 
     } 
     catch(Exception ex) 
     { 
      Logger.Warn("------data received from Serial Port error for HRM-------"); 
      Logger.Error(ex); 
     }; 
    } 
} 
+0

你不能讓這個可靠的SerialPort需要額外的時間關閉()之後,可再次打開之前。最壞的情況是幾秒鐘。您需要將其設置爲「合乎邏輯」的開/關,只需將收到的東西丟棄即可。 – 2013-03-13 23:16:46

回答

1

先通後臺工作線程。

DoWork方法

你可以寫類似的東西

void DoWork{ 
    // init com port 
    while(no body cancelled the background worker){ 
     // if there any waiting data receive and process it. do not use event handlers 
    } 
    // close the serial port so you can open it again later. 
} 

此外,如果你想取消後臺工作這將是一塊蛋糕後

// send cancel command. 
// wait till it is canceled. 
+0

我從記憶中寫下這些對不起,有任何錯誤的關鍵字。 – 2013-03-13 18:11:29

+0

謝謝,馬哈茂德。你能否提供一些關於如何取消或開始工作的示例代碼? – 2013-03-13 18:18:47

+0

一個很好的教程一步一步看看這個http://www.dotnetperls.com/backgroundworker – 2013-03-13 19:12:51