2013-07-15 48 views
1

對於這個問題,我包括整體的一類礦井的目的:System.Timers.Timer使用

public class SerialPortConnection 
{ 
    private SerialPort serialPort; 
    private string ping; 
    double failOut; 
    bool isReceiving; 

    public SerialPortConnection(string comPort = "Com1", int baud = 9600, System.IO.Ports.Parity parity = System.IO.Ports.Parity.None, int dataBits = 8, System.IO.Ports.StopBits stopBits = System.IO.Ports.StopBits.One, string ping = "*IDN?", double failOut = 2) 
    { 
     this.ping = ping; 
     this.failOut = failOut * 1000; 

     try 
     { 
      serialPort = new SerialPort(comPort, baud, parity, dataBits, stopBits); 
     } 
     catch (Exception e) 
     { 
      throw e; 
     } 
    } 

    //Open Serial Connection. Returns False If Unable To Open. 
    public bool OpenSerialConnection() 
    { 
     //Opens Initial Connection: 
     try 
     { 
      serialPort.Open(); 
      serialPort.Write("REMOTE\r"); 
     } 
     catch (Exception e) 
     { 
      throw e; 
     } 

     serialPort.Write(ping + "\r"); 
     var testReceived = ""; 
     isReceiving = true; 

     Timer StopWatch = new Timer(failOut); 
     StopWatch.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
     StopWatch.Interval = failOut; 
     StopWatch.Enabled = true; 

     while (isReceiving == true) 
     { 
      try 
      { 
       testReceived += serialPort.ReadExisting(); 
      } 
      catch (Exception e) 
      { 
       throw e; 
      } 
     } 

     StopWatch.Dispose(); 

     if (testReceived.Contains('>')) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 

    public string WriteSerialConnection(string SerialCommand) 
    { 
     try 
     { 
      serialPort.Write(String.Format(SerialCommand + "\r")); 
      var received = ""; 
      bool isReceiving = true; 

      Timer StopWatch = new Timer(failOut); 
      StopWatch.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
      StopWatch.Interval = failOut; 
      StopWatch.Enabled = true; 

      while (isReceiving == true) 
      { 
       try 
       { 
        received += serialPort.ReadExisting(); 
       } 
       catch (Exception e) 
       { 
        throw e; 
       } 
      } 

      if (received.Contains('>')) 
      { 
       return received; 
      } 
      else 
      { 
       received = "Error: No Data Received From Device"; 
       return received; 
      } 

      StopWatch.Dispose(); 
     } 
     catch (Exception e) 
     { 
      throw e; 
     }   
    } 

    //Closes Serial Connection. Returns False If Unable To Close. 
    public bool CloseSerialConnection() 
    { 
     try 
     { 
      serialPort.Write("LOCAL\r"); 
      serialPort.Close(); 
      return true; 
     } 
     catch (Exception e) 
     { 
      throw e; 
     } 
    } 

    private void OnTimedEvent(object source, ElapsedEventArgs e) 
    { 
     isReceiving = false; 
    } 
} 

什麼我試圖在這裏做的就是保持一個循環運行一組時間量(在這種情況下爲2秒),因爲連接到我正在使用的串行端口的設備是不可預知的。我不知道我會收到什麼數據,我不知道需要多長時間。這是不能修復的,也是我必須要解決的問題。目前,我最好的選擇是等待一段時間,並檢查我收到的結束令牌(「>」)的數據。我已經嘗試連接一個定時器,即使在類如下:

Timer StopWatch = new Timer(failOut * 1000); 
StopWatch.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
StopWatch.Interval = failOut; 
StopWatch.Enabled = true; 

但它似乎並沒有工作。事件本身看起來像這樣:

private void OnTimedEvent(object source, ElapsedEventArgs e) 
{ 
    isReceiving = false; 
} 

我的目標是削減環isReceiving是聯繫在一起:

(while isReceiving == true) 
{ 
    //Do Something 
} 

但它似乎沒有工作。我假設我完全誤解了計時器的功能,但我之前已經有建議來實施它。我究竟做錯了什麼?如果我完全濫用它,我可以用什麼來代替計時器?正如我所說的,我別無選擇,只能等待一段時間,並檢查我收到的內容。除了等待並希望我能得到某些東西之外,無法避免或處理這種情況。

編輯:

也許這是最好的我澄清這一點。 OnTimedEvent事件觸發,變量設置爲false,但不會切斷循環,因爲isReceiving未設置爲false。

編輯2:

帕桑特先生的回答精美的作品禁止一個奇怪的錯誤,我遇到了。因爲我不認爲這是他的回答中的問題,所以更可能是硬件缺陷,或者是其他方面的陌生和模糊,我將他的答案標記爲已接受。我建議任何人選擇實現他的回答也查看我在這裏提出了一個問題:

Apparent IO.Ports.SerialPort Flaw in C# or Possible Hardware Flaw

+0

我認爲你是倍增你的計時器的時間。在你的構造函數中爲'failOut'參數賦值'this.failOut = failOut * 1000',默認值爲'2'。這使它在2000毫秒(或2秒)。然後_later_創建'新的定時器(failOut * 1000)',所以你現在已經做了2000秒_(或33.33分鐘)。我建議你使用'TimeSpan'類來避免這樣的常見錯誤。 –

+0

爲什麼不設置一個每100毫秒命中一次並在其中運行'serialPort.ReadExisting()'的計時器。跟蹤自開始以來的總時間,並且一旦你點擊2秒(或者任何你的'failOut'),就停止計時器。 –

回答

3

您正在對自己太困難。只需將SerialPort.NewLine屬性更改爲「>」即可。並使用SerialPort.ReadLine()來讀取響應。如果需要,仍然可以使用超時,分配SerialPort.ReadTimeout屬性並準備捕獲TimeoutException。

+0

您的答案在99%的時間內很好地工作,但我遇到了一個奇怪的錯誤。我在這裏提交了另一個問題:http://stackoverflow.com/questions/17679459/apparent-io-ports-serialport-flaw-in-c-sharp-or-possible-hardware-flaw謝謝你的時間。我保持這個答案被接受,因爲它似乎不是你的答案中的錯誤,但是.net 4中的錯誤或者我正在使用的設備中可能存在的硬件缺陷。 – DanteTheEgregore

相關問題