2009-04-21 3 views
1

아래 코드가 누락되거나 데이터가 삭제되는 이유를 누구나 알 수 있습니까? 나는 밤새도록 인터넷 검색을하고 있지만 어떤 조언도 찾을 수 없다. 직렬 포트는 다음 설정을 사용합니다. 38400, n, 8,1 xon/xoff 흐름 제어. ReceivedBytesThreshold = 1SerialPort + CF 2.0은 데이터 손실을 막을 수 있습니다.

isReceiving 및 stockReceived는

 private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) 
    { 
     string dataReceived = serialPort1.ReadExisting(); 
     bytecount += dataReceived.Length; 
     processSerialData(dataReceived); 
    } 

    private void processSerialData(string dataReceived) 
    { 
     if (isReceiving == false) 
     { 
      int stxpos = dataReceived.IndexOf('\x02'); 
      if (stxpos != -1) 
      { 
       dataReceived = dataReceived.Replace("\x02", ""); 
       labelcaption = "Receiving... "; 
       this.Invoke(new EventHandler(SetLabel)); 
       isReceiving = true; 
      } 
     } 

     int etxpos = dataReceived.IndexOf('\x03'); 
     if (etxpos != -1) 
     { 
      dataReceived = dataReceived.Replace("\x03", ""); 
      //tmpFile.Write(dataReceived); 
      writeToFile(dataReceived); 
      tmpFile.Close(); 
      isReceiving = false; 
      stockReceived = true; 
     } 

     // Now we need to write the data to file 
     if (isReceiving == true) 
     { 
      if ((bytecount/recordSize) % 100 == 0) 
      { 
       labelcaption = "Receiving... " + (bytecount/recordSize); 
       this.Invoke(new EventHandler(SetLabel)); 
      } 
      //tmpFile.Write(dataReceived); 
      writeToFile(dataReceived); 
     } 
    } 

답변

1

몇 가지 잠재적 인 문제의 형식은 모두 회원 (그들이 문제가있는 말을하지,하지만 그들은 나를 위해 붉은 깃발을 높이)이다 :

  • 문자열을 사용한 다음 인쇄 할 수없는 문자 데이터를 찾고 있습니다. 이것은 용의자 처리 IMO입니다. 바이트를 받고 바이트 값을 찾아야합니다. 기본 인코딩이 할 수있는 일을 누가 알지만, 특히 ASCII 인코딩을 사용하는 경우 일부 캐릭터의 손실은 나를 조금 놀라게하지 않습니다.
  • 잠재적 인 스레드 문제처럼 보입니다. DataRecieved 이벤트를 받으면 데이터를 읽은 다음 수신 처리기의 컨텍스트에서 데이터를 처리합니다. 마지막으로 처리하는 동안 다른 이벤트가 발생하면 어떻게됩니까? 나는 byteCount 변수가 묶여있을 것입니다. 개인적으로 나는 데이터를 받기위한 스레드와 그것을 처리하기위한 스레드를 가지고 있습니다. 최소한 나는 거기에 일종의 동기화 객체를 추가 할 것입니다.
+0

감사합니다 Chris 잠금 블록에서 처리 코드와 동일한 시도를했습니다. 그러나 그것은 작동하지 않았다. 귀하의 의견으로 lock (syncObject) 이외의 다른 것을 사용해야합니까? STX와 ETX 만 ASCII 인코딩에 포함시켜야합니다. 손실 된 데이터는 대용량 파일에서만 발생합니다. 테스트 대상 파일은 약 484KB이며 파일 중간에있는 문자는 문자 그대로입니다. 코드는 항상 stx/etx ok를 선택하는 것으로 보입니다. –

+0

감사합니다 Chris 나는 잠금 블록에서 코드 처리와 동일한 시도를했습니다. 그러나 그것은 작동하지 않았다. 귀하의 의견으로 lock (syncObject) 이외의 다른 것을 사용해야합니까? STX와 ETX 만 ASCII 인코딩으로 분류해야합니다. 손실 된 데이터는 대용량 파일에서만 발생합니다. 테스트 대상 파일은 약 484KB이며 파일 중간에있는 문자는 문자 그대로입니다. 코드는 항상 stx/etx를 픽업하는 것처럼 보입니다. –

1

하나의 DataReceived 패킷에 여러 개의 STX 또는 ETX를 수신하는 경우를 처리하지 못합니다.

0

serialPort1_DataReceived는 트리거 이벤트이므로 주 스레드에서만 발생합니다. 따라서 동시에 2 개의 스레드로 입력 할 수 없습니다. 이를 증명하려면 실행중인 스레드 (Thread.CurrentThread.ManagedThreadId)의 스레드 ID를 출력하십시오.

serialPort1_DataReceived 호출에서 데이터를 스풀링 할 수 있습니다. 직렬 링크에서 활동이 중단되는 것을 보장 할 수있는 경우, 처리가 시작될 때까지 스풀하십시오.

예. 데이터는 X 바이트/문자까지 올 수 있습니다. 그러면 또 다른 문자 세트는 500ms 동안 오지 않을 것입니다. 그런 다음 수신 된 바이트를 처리 할 500ms가 있습니다.

관련 문제