0

我需要一些與後臺工作人員的幫助。我正在嘗試從串口讀取數據(使用按鈕正常工作),問題是我需要不斷從串口讀取數據,直到有人按下窗體上的按鈕(關閉按鈕)以停止讀取。我試圖通過添加一個循環來做到這一點,但它只是無限地運行並凍結了窗體。我有下面的代碼,每當我按下按鈕讀取,一個文件被創建,但是當我按下關閉端口按鈕,它說閱讀串行通信視覺工作室

I/O操作已被中止,因爲任一個線程退出或 應用程序請求

有關如何解決此問題的任何想法?

using System; 
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Data; 
    using System.Drawing; 
    using System.Linq; 
    using System.Text; 
    using System.Windows.Forms; 
    using System.IO.Ports; 
    using System.IO; 

    namespace SerialCommunication 
{ 
    public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     GetAvaliablePortNames(); 
    } 

    bool indicator; 
    StreamWriter sw = new StreamWriter(@"C:\Users\slahiri\Desktop\Data\jumbo.txt"); 

    void GetAvaliablePortNames() 
    { 
     string[] Ports = SerialPort.GetPortNames(); 
     cmbPort.Items.AddRange(Ports); 
    } 

    private void btnOpen_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      if (cmbPort.Text == "" || cmbBaud.Text == "") 
      { 
       MessageBox.Show("Please select the Port and Baud Rates"); 
      } 
      else 
      { 
       serialPort1.PortName = cmbPort.Text; 
       serialPort1.BaudRate = Convert.ToInt32(cmbBaud.Text); 
       serialPort1.Open(); 
       progressBar1.Value = 100; 

       groupBox2.Enabled = true; 
       btnRead.Enabled = true; 

       btnOpen.Enabled = false; 
       btnClose.Enabled = true; 
      } 
     } 
     catch (UnauthorizedAccessException) 
     { 
      txtRead.Text = "Unauthorized Acess"; 
     } 
    } 

    private void btnClose_Click(object sender, EventArgs e) 
    { 
     serialPort1.Close(); 
     progressBar1.Value = 0; 
     btnClose.Enabled = false; 
     btnRead.Enabled = false; 

     btnOpen.Enabled = true; 
     indicator = true; 


    } 



    private void btnRead_Click(object sender, EventArgs e) 
    { 
     if (btnRead.Text == "Read") 
     { 

      btnRead.Text = "Stop and Close Port"; 
      progressBar1.Maximum = 1000; 
      progressBar1.Value = 0; 
      backgroundWorker1.RunWorkerAsync(progressBar1.Maximum); 
      indicator = false; 
     } 
     else 
     { 

      backgroundWorker1.WorkerSupportsCancellation = true; 
      backgroundWorker1.CancelAsync(); 

     } 
    } 


    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     try 
     { 
      int max = (int)e.Argument; 
      int n = 0; 
      indicator = false; 
      do 
      { 
       //write to serial writer 
       sw.WriteLine(serialPort1.ReadLine()); 
       if (backgroundWorker1.CancellationPending) 
       { 
        sw.Flush(); 
        sw.Close(); 
        e.Cancel = true; 
        break; 
       } 
       // backgroundWorker1.ReportProgress(n++); 
      } 

      while (indicator ==false); 
     } 
     catch (TimeoutException) 
     { 
      //Close Serial Writer & Messagebox 
      //txtRead.Text = "Time Out!"; 
      MessageBox.Show("TimeOut Exception"); 
     } 

    } 

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     //progressBar1.Value = e.ProgressPercentage; 
    } 

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     btnRead.Text = "Read"; 
     //close serial writer 
    } 

} 

}

+0

你打開'SerialPort'的某個地方嗎? –

+0

在開放串行端口按鈕中,沒有包含,因爲我雖然不相關,您是否希望我添加它? – Shankulah60

+0

它會避免這樣的問題;) –

回答

0

既然你有一個做,而構建您評估在年底的條件! 因此,當您點擊Close按鈕並關閉SerialPort時,後臺工作仍處於活動狀態,並在後臺運行,試圖從SerialPort中讀取。它進入do隔間並嘗試從封閉的端口讀取,就像運行一個關閉的門一樣:)這導致了異常。

您可以通過

1)將在頂部,而評估解決它,擺脫do聲明(使其成爲一個簡單的while循環)。這樣serialPort.ReadLine將不會再執行,因爲您在點擊關閉按鈕時設置了indicator = true;

可能是在這種情況下,你應該把indicator設置爲第一線關閉端口之前:

private void btnClose_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     indicator = true; 
     serialPort1.Close(); 

或者

2)把一個額外的,如果條款,確保爲只讀如果端口是開放的!

if (serialPort1.IsOpen) 
{ 
    sw.WriteLine(serialPort1.ReadLine()); 
} 
+0

感謝您的幫助! – Shankulah60

+0

@ Shankulah60不客氣,當你點擊關閉按鈕時,你也可以用'if(!backgroundWorker1.IsBusy)'來檢查,然後關閉端口。因爲那樣你可以確定他沒有試圖從港口讀取 –