2012-10-16 3 views
0

직렬 포트 관련 응용 프로그램에서 작업 중입니다. SerialPortDataReceived 이벤트를 사용하는 동안 내가받은 바이트 텍스트 상자를 업데이트해야합니다 작업을 종료하기 전에 InvokeRequired를 올바르게 사용하십시오.

private void Connection_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    ledReceive.On = true; 

    var data = Connection.ReadExisting(); 

    _readBuffer.Add(data); 
    Invoke(new EventHandler(AddReceivedPacketToTextBox));  
} 

그래서 나는 텍스트 상자를 업데이트 Invoke를 사용합니다. 그러나 큰 문제가 있습니다. 연결을 닫으려고 할 때 UI가 얼어 버린 것 같습니다. 아마도 Invoke이 아마도 somehing을하고 있다고 생각합니다.

친구는 내가 RequiredInvoke을 사용해야한다고 말했지만, 나는 그가 정말로 뭘 말하고 있는지 전혀 모른다. 호출 및 UI 스레드를 엉망으로 만들지 않고 연결을 닫을 수 있습니까? 나는 완전히 잘 모르겠지만, 당신이 동결 이유를 설명 할 수있는 연결을 닫을 때 나는 당신의 UI를 업데이트하는 스레드를 제거 추측 할

private void DisconnectFromSerialPort() 
{ 
    if (Connection != null && Connection.IsOpen) 
    { 
     Connection.Close(); 
     _receivedPackets = 0; //reset received packet count 
    } 
} 

답변

1

: 여기

내 가까운 방법입니다 . 하지만 모든 코드를 파헤 치지 않고 확신 할 수는 없습니다.

InvokeRequired는 요소에 액세스하려는 스레드가 UI에 기본이 아닌 경우 true를 반환합니다.

// Summary: 
    //  Gets a value indicating whether the caller must call an invoke method when 
    //  making method calls to the control because the caller is on a different thread 
    //  than the one the control was created on. 
    // 
    // Returns: 
    //  true if the control's System.Windows.Forms.Control.Handle was created on 
    //  a different thread than the calling thread (indicating that you must make 
    //  calls to the control through an invoke method); otherwise, false. 

그리고 기본적인 구현 : 당신은 MS의 explaination 선호하는 경우 또는 호출이 함수가 제일 먼저해야

public void ReceiveCall() 
    { 
     if (this.InvokeRequired) 
     { 
      this.Invoke(new CallDelegate(ReceiveCall), new object[] { }); 
      return; // Important to not continue on this method. 
     } 

     // Whatever else this function is suppose to do when on the correct thread. 
    } 

를, 당신의 UI에 깊이 들어 가지 스레드를 방지합니다. 이제 연결 자체가 UI 스레드의 경계 내에 있다고 판단되면 "InvokeRequired"가 트리거되지 않습니다. 이 문제를 방지하는 한 가지 방법은 연결에 바인딩되지 않은 UI를 업데이트하는 스레드를 수동으로 만드는 것입니다.

여러 UI 요소의 렌더링을 업데이트하는 것과 비슷한 문제가있었습니다. 시계는 정상적으로 작동하지만 모든 UI가 렌더링 될 때까지 "정지"합니다. 많은 UI가있는 경우에는 다음 틱을 건너 뛸 수 있습니다.

 Thread updateUI = new Thread(updateUIDelegate); 
    updateUI.Start(); 

이렇게하면 내 시계 (또는 연결)가 자체적으로 물건을 처리하는 독립적 인 스레드를 시작하게됩니다. Monitor 클래스 또는 lock 키워드를 검사하여 동일한 변수를 사용하여 스레드가 충돌하거나 여러 스레드가 충돌하지 않도록 할 수 있습니다.

편집 : 답변 What causes my UI to freeze when closing a serial port?

+0

감사 : 또는 당신은 아마 나보다 더 이해에서 멋진 대답을 읽을 수 있습니다. 왜 2 개의 똑같은 질문이 생겼는지 아무 아이디어도 !! –

관련 문제