2012-08-02 2 views
0

.NET 4.0에서 응답을 기다렸다가 응답을 반환 할 수 있습니까? SerialPort 응답을 기다립니다.

은 현재 내가 이런 식으로 일을 해요하지만 정말 좋은하지 않고 나는 그것을 좋아하지 않아 :

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     byte[] options = new byte[]{1,1,0}; 
     COMManager mgr = new COMManager("COM1"); 

     byte[] result = mgr.GetResponse(options); 
    } 
} 

그리고 내 COM 관리자 클래스 (나는 별도의 작업을해야 할 클래스 (dll)) :

public class COMManager 
    { 
     SerialPort sp = null; 
     byte[] result = null; 
     bool completed = false; 

     public COMManager(string comport) 
     { 
      sp = new SerialPort(comport); 
      sp.DataReceived +=new SerialDataReceivedEventHandler(sp_DataReceived); 
     } 

     public byte[] GetResponse(byte[] option) 
     { 
      sp.Write(option, 0, option.Length); 
      //I don't like the way... 
      while (!completed) { } 
      completed = false; 
      return result; 
     } 

     void sp_DataReceived(object sender, SerialDataReceivedEventArgs e) 
     { 
      result = new byte[sp.BytesToRead]; 
      sp.Read(result, 0, sp.BytesToRead); 
      completed = true; 
     } 
    } 

우리는 "await"문을 사용할 수 있습니다. 그러나 현재 프로젝트에서는 .NET 4.0 만 사용할 수 있습니다. 아이디어가 있으십니까?

답변

1

원래 질문의 경우 실행 스레드를 차단하려면 응답을 얻었을 때 Set이되는 ManualResetEvent 또는 AutoResetEvent을 사용할 수 있습니다. 이 페이지에는 꽤 좋은 설명이 있습니다.

스레딩의 경우, 수행중인 작업에 대해 명확하지 않은 경우 수행하지 않는 것이 좋습니다.

NB : 이벤트에 액세스 할 때 동기 차단은 낭비처럼 보입니다. 데이터가 스트림임을 고려하면 추상화를 유지하기가 어려울 수 있습니다.

+0

안녕하세요 Asti. 답장을 보내 주셔서 감사합니다. 전에 ManualResetEvents를 사용하지 않았습니다. 그래서 "개인 정적 ManualResetEvent mre = new ManualResetEvent (false);"추가합니다. 내 COMManager 클래스 및 "mre.Reset()"내 while 루프를 바꿉니다. 그리고 dp_DataReceived 완료된 = true 대신 mre.Set() 설정? – user1011394

+0

@ user1011394 네, 기본적으로. 정적이라고 선언하지 마십시오. – Asti

+0

AutoResetEvent는 설정 한 후 자동으로 재설정되므로 원하는 경우 Reset을 호출 할 필요가 없습니다. – Asti

2

깨끗한 방법은 AutoResetEvent을 기다려야하고 수신 콜백이이를 알리는 것입니다.

이 방법으로 래퍼를 생성하면 .Net의 모든 버전에서 await을 효과적으로 사용할 수 있습니다.

2

비동기 적으로 읽지 않으려는 경우 DataReceived 이벤트를 사용할 필요가 없습니다. GetResponse()에서 직접 Read() 메서드를 호출하면됩니다.

완전한 응답을 얻을 것이라고 가정 할 수 없으므로 Read()의 반환 값을 무시할 수 없습니다. 대개 2 바이트 만 반환하며 직렬 포트는 꽤 느립니다. 따라서 전체 응답을 얻을 때까지 Read()를 계속 호출해야합니다.

+0

Hans Passant, 비동기 호출입니다. 먼저 바이트를 써야하고 (장치로 보내면됩니다.) 둘째, 장치가이를 해석하고 개별 응답을 보냅니다. – user1011394