2012-08-29 1 views
1

시리얼 포트를 통해 데이터를 수신하기위한 핸들러에서 데이터를 수신 할 때이를 문자열에 저장하고 .contains 검색을 수행하여 데이터로 처리해야하는지 확인합니다. 응용 프로그램이 유휴 상태 일 때 (모뎀이라고 부름) "연결됨"과 같은 메시지를 보내면 정상적으로 작동합니다.시리얼 데이터는 메시지 박스에서만 작동합니다.

문제는 컴퓨터를 폴링하는 경우입니다. 반환 결과를 기대하는 명령을 시작할 때 작동하지 않으며 이유를 파악할 수 없습니다. 이제 메시지 상자로 함수를 시작하면됩니다. 차라리 불필요한 메시지 함을 갖고 싶지 않습니다.

다음은 내 코드 샘플입니다.

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) 
{ 
    if (this.InvokeRequired) 
    { 
     RefreshTextBox d = new RefreshTextBox(RefreshTextBoxResults); 
     Invoke(d); 
    } 
    else 
    { 
     RefreshTextBoxResults(); 
    } 
} 

private void RefreshTextBoxResults() 
{ 
    //MessageBox.Show("refresh text is occurring"); 
    indata1 = serialPort1.ReadExisting(); 
    rx.AppendText(indata1); 

    string dataCheck = indata1.ToUpper(); 

    //MessageBox.Show(dataCheck); 
    if (indata1.ToUpper().Contains("CONNECT"))//dataCheck.Contains("CONNECT")) 
    { 
     // MessageBox.Show("connect"); 
     cState.Text = "Connected"; 
     if(connected==false) 
      connectLink(); 
    } 
    if (dataCheck.Contains("CONNECTED")) 
    { 
     // MessageBox.Show("Active Call in Session"); 
     cState.Text = "Connected"; 
     if (connected==false) 
      connectLink(); 
    } 
    if (dataCheck.Contains("NO")) 
    { 
     cState.Text = "Disconnected"; 
     disconnect(); 
    } 
    if (dataCheck.Contains("CAMPOS")) 
    { 
     campos = indata1; 
     camDat = true; 
    } 
} 

private void cState_Click(object sender, EventArgs e) 
{ 
    writeDevice("callstatus"); 
} 

public void writeDevice(string cmd) 
{ 
    try 
    { 
     { 
      serialPort1.Write(cmd + "\r\n"); 
     } 
    } 
    catch 
    { noconnect(); } 
} 

cstate()를 실행하면 호출 상태와 유형이 있으면 입력해야합니다. 모뎀이 내 프롬프트 상자에서 볼 수있는대로 응답합니다. 연결된 단어가 그곳에 있으면 "연결됨"이라고 말하기 위해 레이블의 텍스트를 변경해야합니다. 코드가 위치하므로 해당 레이블에는 아무런 변화가 없습니다. 그러나 해당 MessageBox를 활성화하는 RefreshTextBoxResults()의 첫 번째 줄에 주석을 제거하면 모뎀의 상태가 감지됩니다.

나는 무슨 일이 일어나는지 보지 못했습니다. 누군가 왜 이런 일이 일어 났는지 설명 할 수 있습니까?

+0

메시지 상자 안에 indata1을 넣고 보여 주려고 했습니까? – SolidSnake

+0

if (indata1.ToUpper(). Contains ("CONNECT")) 및 if (dataCheck.Contains ("CONNECTED")) 같은 일을하는 것입니다. –

+0

그리고 다른 이유가 있으면 ifs를 사용하는 이유는 무엇입니까? – SolidSnake

답변

2

, 나는) (RefreshTextBoxResults에서 첫 번째 줄에 주석을 제거하면

키 문구의

. 문제는 ReadExisting()을 사용한다는 것입니다. 직렬 포트가 매우 느리면 DataReceived 이벤트 처리기는 일반적으로 한두 개의 문자 만 가져옵니다. 메시지 상자를 표시하면 이 느려집니다.. 이를 통해 직렬 포트 드라이버는 을 더 읽습니다. 문자입니다. ReadExisting이 "C"또는 "Co"대신 "Connected"문자열 전체를 읽는 데 충분합니다.

디버거를 사용할 때도 진단하기가 어려우므로 코드를 한 단계 씩 실행해도 포트가 충분한 문자를 얻을 수있을만큼 속도가 느려집니다.

전체 응답 문자열을 얻은 후에 만 처리하면됩니다.. 모뎀으로 항상 쉽습니다. ReadExisting() 대신 ReadLine()을 사용하십시오. NewLine 속성의 값을 조정해야 할 수도 있습니다.

+0

나는 그것을 시험해야 할 것이다. 모뎀을 정확히 사용하지는 않지만 비슷한 특성을 많이 갖고 있습니다. – eatumup

+0

이것은 황금 티켓이었다. 감사! – eatumup

1

MessageBox()은 모달 대화 상자 메시지 루프를 시작하여 대기중인 창 메시지에 처리 기회를 허용합니다. RefreshTextboxResults() 함수에서 텍스트 상자 컨트롤에 수행하는 조작 중 일부는 컨트롤 창 핸들에 메시지를 게시하는 것으로 생각할 수 있습니다. 이 경우 실행 흐름이 메시지 루프에 들어가거나 메시지 루프로 돌아올 때까지 창 핸들은 이러한 메시지를 수신하지 않습니다. MessageBox와 같은 모달 대화 상자를 열면 함수에서 이러한 일이 발생합니다.

해결 방법이 아니지만이 이론을 확인해야합니다. MessageBox()Application.DoEvents()으로 바꾸어보십시오. (귀하의 응용 프로그램이 WinForms 응용 프로그램이라고 가정합니다.) 이렇게하면 MessageBox()을 호출 할 때와 같은 정도로 방해물을 지우면 처리해야하는 메시지 대기열에 쌓여있는 보류중인 메시지가 있음을 분명히 알 수 있습니다.

+0

나는 MessageBox()를 Application.DoEvents()로 대체했고 MessageBox와 같은 결과를주지 않았다. – eatumup

+0

그래, 문제는 대기중인 메시지가 아닙니다. – dthorpe

0

데이터가 완전히 수신되거나 작업을 수행하기 위해 백그라운드 트레드를 사용할 수있을 때까지 응용 프로그램을 차단하는 것이 좋습니다.