2011-02-07 3 views
2

직렬 포트를 통해 PC에 연결된 GSM 모뎀에서 AT 명령에 대한 응답을 구문 분석하는 프로그램을 작성하고 있습니다. 이 프로그램에서는 직렬 포트의 모든 응답을 "수신 대기"하는 스레드가 있습니다. 그런 다음 명령 실행을 요청한 스레드 (이 큐에 항목이 게시되는 동안 차단됨)에 대한 큐에 대한 응답을 보내거나 Unsolicited Result Code의 수신을 알리는 이벤트를 생성 할 수 있습니다.SerialPort.ReadLine()에 대한 호출 종료

현재 스레드 (메서드)는 SerialPort.ReadLine 메서드를 기반으로하며 "GsmModem"이라는 클래스에 포함되어 있습니다. GsmModem.Close() 메서드가 호출 될 때. "청취자"스레드에 신호를 보내서 종료하고 나서 직렬 포트가 닫힐 때까지 기다려야합니다. 현재의 코드는 직렬 포트의 타임 아웃 예외에 의존하기 때문에 그다지 우아하지 않습니다. 쓰레드는 Timeout 예외를 던지고 ManualResetEvent 플래그를 체크하는 serialPort.ReadLine()으로 돌아 간다. 나는 이것을 피하고 싶습니다.

이 SerialPort.Readline()에 대한 호출을 중단 할 수 있다면 모든 곳에서 보았지만 유일한 해결책은 시간 초과 예외 인 것 같습니다. 이것은 경우

다른 가능한 방법은 가 데이터를 처리하거나 원치 않는 응답이 수신 될 때 (내가 아는 그나마 새로운 라인을 받았을 때 그것을 대기열하거나 새로운 이벤트를 발생 이벤트를 SerialPort.DataReceived 사용하는 것 좋은 생각).

실제 코드는 다음과 같습니다

private void ModemListenerThread() 
{ 
    if (this._serialPort.IsOpen) 
    { 
     //Execute the thread wile we don't receive the "endThreadSignal" 
     while(!this._endThreadEvent.WaitOne(0)) 
     { 
      // Catch TimeoutException and spin checking for the ManualResetEvent 
      try 
      { 
       // Read line 
       string line = this._serialPort.ReadLine(); 
       if (String.IsNullOrWhiteSpace(line)) 
        continue; 
       //Check if no command was sent (not definitive code) 
       if (_modemIsIdle) 
        this.OnUnsolicitedResponse(new EventArgs()); 
       else 
       { 
        //Enqueue as reply to command() 
        lock ((this._itemQueue as ICollection).SyncRoot) 
        { 
         _itemQueue.Enqueue(line); 
         this._itemPostedEvent.Set(); 
        } 
       } 
      } 
      //Timeout is necessary to avoid the thread to block indefinitely 
      catch (TimeoutException ex) 
      { 
       continue; 
      } 
     } 
    } 
} 

회신의 처리를 구현하는 방법에 대한 어떤 제안을 감상 할 수있다. 내 주요 질문은 여기에 있습니다 : readline 호출을 중단 할 수 있습니까? 그렇지 않다면 SerialPort.DataReceved 이벤트에 논리를 구현할 수 있습니까? 마지막으로 더 나은 것을 제안 할 수 있다면 좋을 것입니다.

의견이나 도움을 주셔서 감사합니다.

+0

마지막으로 .NET 직렬 코드를 마지막으로 회상했던 것처럼 직렬 포트에 수신기를 연결하여 .ReadLine()을 수행하는 대신 수신기를 연결했지만 지금은 잊어 버리기 때문에 이해가되고 도움이된다면 .. 미안해. 그게 바로 내가 가진 전부입니다. 그렇지 않으면, 이것은 좋은 질문이며, 나는 당신에게 행운이 있기를 바라고 있습니다. – jcolebrand

답변

1

SerialPort.DataReceived 이벤트를 사용하는 것이 좋습니다. 직렬 데이터에 대한 자체 버퍼를 유지하는 것을 의미하지만, 그다지 복잡하지는 않습니다. 이 작업을 수행하면 리스너 스레드를 유지 관리 할 필요가 없습니다. 대신 직렬 포트를 닫을 준비가되면 DataReceived 대리자를 제거하고 포트를 닫으십시오.

SerialPort.ErrorReceived 이벤트도 처리하는 것이 좋습니다. 당신은 이미 이것을하고 있을지도 모른다.

+0

네, 이전에 얘기 한 내용입니다. – jcolebrand

+0

Joel and drachenstern, 직렬 포트가 열려있을 때 스레드가 생성된다는 것을 알았습니다. 대리인의 코드가 직렬 포트 스레드에서 실행된다고 가정합니다. 그 길로 갈 것 같습니다. 누구든지 어떤 제안이라도 듣고 싶습니다. 다시 한번 감사드립니다. – RubenSAZ

+0

Joel, 답변이 더 이상 없기 때문에 귀하의 답변을 수락했습니다. 고맙습니다. – RubenSAZ