2010-02-19 4 views
4

MSDN 문서에서 DataReceived 이벤트가 반드시 바이트 당 한 번 발생하지 않는다는 것을 알고 있습니다..NET SerialPort 클래스 DataReceived 이벤트가 실행되는 이유는 무엇입니까?

하지만 누가 이벤트를 발생시키는 메커니즘이 정확히 무엇인지 압니까?

각 바이트를 수신하면 이벤트가 시작되기 전에 바이트 사이에 10ms에 도달해야하는 타이머가 다시 시작됩니까?

직렬 포트에서 들어오는 XML 데이터를 읽는 앱을 작성하려고하기 때문에 질문합니다.

내 노트북에는 직렬 포트가 없으므로 가상 직렬 포트 에뮬레이터를 사용합니다. (나는 알고있다, 나는 알고있다 - 나는 ATM에 관해서는 아무것도 할 수 없다).

에뮬레이트 된 포트를 통해 데이터를 응용 프로그램에 전달할 때 각 XML 레코드 (약 1500 바이트)마다 이벤트가 한 번 발생합니다. 완전한. 그러나 다른 사무실의 동료가 실제 케이블로 연결된 두 대의 컴퓨터를 사용하여 시도 할 때 DataReceived 이벤트는 10 바이트 정도의 XML이 끝날 때마다 반복적으로 발생합니다. 이는 앱에서 완전히 벗어납니다.

답변

6

DataReceived는 하나 이상의 바이트를 읽을 준비가되면 언제든지 시작할 수 있습니다. 그것이 발사 될 때 정확히 OS와 드라이버에 의존하며, 또한 수신되는 데이터와 .NET에서 실행되는 이벤트 사이에 약간의 지연이 있습니다.

제어 흐름에 대한 DataReceived 이벤트의 타이밍에 의존해서는 안됩니다.

대신 기본 프로토콜을 구문 분석하고 전체 메시지를받지 못한 경우 더 기다립니다. 둘 이상의 메시지를받는 경우 왼쪽 메시지가 다음 메시지의 시작이 될 것이므로 첫 번째 메시지를 구문 분석하지 않도록하십시오.

+2

예, 일반적으로 직렬 포트 데이터는 효율적으로 버퍼링되므로 업데이트가 거의 예측할 수 없습니다. Mark가 설명한 것과 비슷하게 ReadExisting을 반복적으로 호출하고 데이터의 모든 메시지를 처리하며 완료된 메시지를 저장하는 타이머를 설정했습니다. GPS 장치로이 작업을 수행 할 때 메시지에 체크 합계가 포함되어 있으므로 무결성 및 완전성을 검증하여 잘리지 않았는지 확인할 수 있습니다 (이 경우 다음 ReadExisting에서 나머지 메시지를 가져옵니다). 나는 이것을 래퍼 (wrapper)에서 사용했고, 차례로 각 완전한 메시지에 대한 이벤트를 발생시켰다. – AaronLS

2

Mark Byers가 지적했듯이 이것은 운영체제와 드라이버에 따라 다릅니다. 가장 낮은 레벨에서, 표준 RS232 칩 (저의 삶 동안, 모든 사람들이 '표준'을 만들기 위해 복사 한 것을 기억하지 못합니다)은 인바운드 레지스터에 데이터가있을 때 인터럽트를 발생시킵니다. 드라이버의 하단은 칩의 버퍼 크기까지 데이터를 가져 와서 드라이버의 버퍼에 저장하고 데이터가있는 OS에 신호를 보내야합니다. 이제는 .NET Framework에서 데이터를 사용할 수 있음을 알 수 있습니다. OS가 직렬 포트를 연 응용 프로그램 (OS 레벨 작업이고 .NET 프레임 워크에서 OS/드라이버 수준 구현으로의 '실제'링크 제공)을 알리는 시점에 따라 문자 그대로 데이터의 양이 달라질 수 있습니다 > 1 바이트를 버퍼에 저장해야합니다. 왜냐하면 드라이버의 하단이 더 많은 데이터를로드 할 수 있기 때문입니다. 제 생각에는 시스템에서 드라이버가 거대한 버퍼를 제공하고 있으며 데이터 스트림에서 중요한 일시 정지 이후에 신호를 보내는 것뿐입니다. 반면에 동료의 시스템은 훨씬 더 자주 신호를 보냅니다. 다시 말하지만, 프로토콜을 구문 분석하는 Mark Byer의 조언이 자리 매김하고 있습니다. TCP 소켓을 통해 유사한 시스템을 구현 했으므로 상황을 처리 할 수있는 유일한 방법은 전체 프로토콜 메시지를 얻을 때까지 데이터를 버퍼링 한 다음 전체 메시지를 응용 프로그램에 전달하는 것입니다.

+0

예, 원래 아키텍처는 직렬 포트를 폴링하고, 데이터를 버퍼링하고, 시작 및 종료 태그를 찾아 완전한 XML 레코드를 추출하고, 나머지를 버퍼링하는 것에 기반을두고있었습니다.DataReceived 이벤트가 작동하면서 전체 버퍼링 시나리오가 단순해질 수 있다고 생각할 때 너무 흥분했습니다. 그러나 아아, 이제 버퍼를 다시 구현하고 태그를 다시 찾아야합니다. – Klay

+0

@Klay - 버퍼 구현이 그렇게 나쁘지 않습니다. 내 말은, 적어도 당신은 폴링을 제외 할 수 있습니다. –

관련 문제