2017-09-07 10 views
1

멋지고 멋진 C# 프로그램이 있지만 연속적으로받은 바이트의 처리가 너무 느립니다. 그리고 나는 아마도 배경 작업자를 사용하여이 문제를 해결할 수 있다고 생각하지만 나는 그것에 대한 경험이 없으며 이전의 모든 시도는 실패했습니다.C#이 설정에서 배경을 구현하는 방법은 무엇입니까?

private void serial_DataReceived(object sender, SerialDataReceivedEventArgs e) 
     { 
      rxBuffer += serial.ReadExisting(); // add new bytes to the string 'rxBuffer' 

      this.Invoke(new EventHandler(serialReceived)); 
     } 

     private void serialReceived(object s, EventArgs e) 
     { 
      while (rxBuffer.Length > 0) // keep processing bytes until the string is empty 
      { 
       // textBox1.Text += rxBuffer[0]; 
       byte b = Convert.ToByte(rxBuffer[0]); 
       string hexValue = b.ToString("X"); 

       rxBuffer = rxBuffer.Remove(0, 1); // removes the 'captured' byte from the string 
       ..... 
       lots of code 

이 루프는 본질적으로 내 전체 프로그램의 75 %입니다. 이해가 안되는 바이트
contoll UI 요소는 텍스트 파일을 저장하거나 읽을 수 있으며 직렬 포트를 통해 바이트를 되돌려 보낼 수 있습니다.

이 시스템은 작동하지만 속도가 너무 느립니다. 따라서 백그라운드 작업자에서 while 루프를 움직여 문제를 해결할 수 있다고 생각합니다.

현재 코드 설정에서 백그라운드 작업자를 구현하려면 어떻게해야합니까? 지금까지 내 모든 시도는 실패했습니다.

편집 : 아래에 댓글을 달았습니다. 나는 모든 단일 바이트와 함께 serial_DataReceived이 호출 될 것이라고 생각했다. 내 응용 프로그램에서 2 바이트를 수신 한 후 2 바이트 사이에 2ms의 지연이 발생합니다. ReadExisting()은 1 바이트 이상을 반환하는 경우가 있습니다. 따라서 직렬 이벤트에서 지연이 발생합니다. 나는 Qt에서도 이것을 가지고 있었지만 이것은 결코 문제가 아니었다. 나는 전체 문자열을 한꺼번에받는 기능이라고 생각한다.

나는 개인적으로 invoke()이 모든 것을 느리게 만들 것이라고 생각하지만 이전의 C#에 대한 경험이 없으므로 어쨌든 나는 모든 솔루션을 공개하고 있습니다.

+0

백그라운드 작업자를 어떻게 활용할 수 있는지 알려주는 링크입니다. https://stackoverflow.com/questions/6481304/how-to-use-a-backgroundworker –

+1

'ReadExisting'을 사용하는 이유는 무엇입니까? 특히 실제로 바이트에 관심이 있다면? =! [SerialPort.Read] (https://msdn.microsoft.com/en-us/library/ms143549 (v = vs.110) .aspx) 바이트를 버퍼로 직접 읽습니다. 전체 문자열 처리가 실제로 느린 프로세스 인 것처럼 보입니다. 백그라운드에 넣는다면 더 빠르지 않을 것입니다. 이미'serial_DataReceived' 이벤트를 구현 했으므로 프로세스는 이미 백그라운드 스레드에 있습니다. –

+0

'많은 코드 '에서'Invoke' 호출이 필요합니까? 전화가 아마도 그렇게 느린 (그리고 문자열 처리에 대한 내 이전의 가정이 잘못되었습니다) –

답변

0

이 코드가 해결책 인 것 같습니다. 내 GUI가 signicantly 실행되는 것을 알 부드러운

나는 isBusy() 플래그를 사용하여 시도했지만 내가 대신 시도 및 캐치 블록을 사용하므로 작동하지 않았다
private void serial_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     rxBuffer += serial.ReadExisting(); 

     try { backgroundWorker1.RunWorkerAsync(); } catch { } 
    } 


    private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) 
    { 
     //private void serialReceived(object s, EventArgs e) 
     //{ 
     while (rxBuffer.Length > 0) 
     { 
      // textBox1.Text += rxBuffer[0]; 
      byte b = Convert.ToByte(rxBuffer[0]); 
      string hexValue = b.ToString("X"); 

      rxBuffer = rxBuffer.Remove(0, 1); 

.

serial_Datareceived는 rxBuffer 문자열에 새 바이트를 계속 추가하고 backgroundworker는 rxString의 모든 단일 바이트가 처리되도록합니다.

EDIT : 문제가 있습니다. 패널을 제외하고 UI 요소를 제어 할 수 없습니다. 방금 알았어. 나는 여전히 다른 스레드에있을 때 UI 요소에 액세스하려고합니다.

0

사람들이 직렬 포트를 통해 명령을 보내고받는 많은 질문을 봅니다. 컴퓨터/장치 간의 비동기 통신을 연속적으로 수행하기 위해 백그라운드 작업자와 상태 시스템을 사용하는 것에 대해 이야기하는 좋은 예가 여기에 있습니다. https://stackoverflow.com/a/38536373/2009197 별도의 스레드에서 데이터를받을 때 UI 스레드 업데이트를 호출해야합니다.