2015-01-20 1 views
0

올바르게 작동하는 직렬 포트를 통해 데이터를 읽습니다. 다음은 내 짧은스레드 슬립 직렬 포트 데이터 이벤트 처리기를 차단하는 중

public Form1() 
{ 
    InitializeComponent(); 

    //Background worker 
    m_oWorker = new BackgroundWorker(); 
    m_oWorker.DoWork += new DoWorkEventHandler(m_oWorker_DoWork); 
    m_oWorker.ProgressChanged += new ProgressChangedEventHandler(m_oWorker_ProgressChanged); 
    m_oWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_oWorker_RunWorkerCompleted); 
    m_oWorker.WorkerReportsProgress = true; 
    m_oWorker.WorkerSupportsCancellation = true; 


    connectComPort.DataReceived += new SerialDataReceivedEventHandler(receiveData); 
    enableDisable(); 
} 

void m_oWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     backProcess(); 
     m_oWorker.ReportProgress(100); 
    } 

private void backProcess() 
{ 
    //do some work 
    Thread.Sleep(10000); 
    if(check if 2000 bytes received) 
    { 
     //do some work 
    } 
} 

backProcess을 코드() 백그라운드 작업자에서 실행하고 나는 시리얼 포트로부터받은 바이트를 삽입하는 글로벌 큐를 가지고 있고 루프 경우에이 큐를 확인합니다.

내 문제는 2000 바이트가 다른 끝에서 PC로 전송 될 때 thread.sleep 문까지 1000 바이트 이하를 수신하지만 thread.sleep 단계에서 중단 점을 설정하면 전체 2000 바이트가 수신된다는 것입니다. 그럼 thread.sleep (백그라운드 스레드) 블록 데이터 수신 이벤트 핸들러도? 이 문제를 어떻게 피할 수 있습니까?

+0

'backProcess'가 백그라운드 작업자'm_oWorker'와 어떤 관련이 있는지 알 수 없습니다. – kennyzx

+3

단순히 디버거 중단을 사용하여 절전 모드를 늘린 것입니다. 드라이버는 디버거 중단이 활성화되어있는 동안 계속 데이터를 수신합니다. 전체 접근 방식에 큰 결함이 있습니다. DataReceived 이벤트 처리기에서받은 바이트 수를 2000 바이트로 처리해야합니다. 스레드가 대기 할 때까지 기다리지 않아도됩니다. –

답변

2

일부 사항은 귀하의 질문에서 명확하지 않지만 귀하의 디자인에 결함이있는 것으로 생각됩니다.

배경 작업자가 전혀 필요 없으며 일부 스레드를 잠자기 할 필요가 없습니다.

직렬 입력을 처리하는 가장 좋은 방법은 SerialPort 클래스의 이미 비동기식 인 DataReceived 이벤트를 사용하는 것입니다.이 이벤트는 읽을 데이터가있을 때마다 호출됩니다 (사용자가 이미이 작업을 수행하고 있습니다. 편집하다).

기존 데이터를 읽고 StringBuilder에 추가하거나 최대 2000 바이트의 목록을 채우고 거기에서 원하는 것을 실행할 수 있습니다.

의사 코드 예제는 다음과 같습니다

DataReceived event 
    1. Read data (using `SerialPort.ReadExisting`) 
    2. Append Data to buffer, increase total number of bytes read 
    3. If number of bytes >= 2000: Spawn new thread to handle the data 

BackgroundWorker이 방법에 의해,이에 적합한 도구가 아닙니다! 2000 바이트를 처리하는 것이 빠르다면 새 스레드를 전혀 생성 할 필요가 없습니다.

+0

답장을 보내 주셔서 감사합니다. 백그라운드 작업자를 사용하여 직렬 포트를 통해 장치에 명령을 보내고 장치에서받은 데이터를 확인하고 있습니다. 통신이 잠시 진행되기 때문에 UI 스레드를 차단하고 싶지 않아 통신 위젯 장치에 백그라운드 작업자를 사용하고있었습니다. – prattom

+0

'DataReceived' 이벤트가 이미 비동기이므로 불필요합니다. –