2009-03-05 3 views
2

현재 네트워크의 데이터를 수신하고 규칙을 실행하는 스레드가 있습니다. 그런 다음 GUI에 데이터를 전달하려고합니다. GUI에서 교착 상태가 발생할까봐 걱정됩니다. GUI 측면에서 뮤텍스를 넣는 것이 불가능하다는 것을 알아 냈습니다. 나는 또한 C# 및 dotnet 3.5를 사용하고있다.Winform은 다중 스레드 또는 이벤트 타이머를 사용해야합니까?

내가 뭘 생각해 냈는지는 입니다. 1) 타이머를 사용하여 이벤트를 만들고 스레드를 덤프하십시오. 성능이 걱정됩니다. 2) 중간 이벤트를 사용하여 데이터를 GUI에 복사하십시오. 3) GUI를 사용하여 스레드로부터 안전한 방법을 찾아서 찾아냅니다.

진행하는 가장 좋은 방법은 무엇이라고 생각하십니까?

편집 : 여기 제가 사용하고있는 해결책이 있습니다. 변경된 요소를 전달한 다음 큰 객체를 뮤텍스로 보호합니다. InvokeRequired를 사용하여 스레드를 전환 한 다음 BeginInvoke를 대리자와 교환하기 위해 도우미 함수를 사용합니다. 답변을 읽은 다음 Threading in Windows Forms에 도달 할 때까지 Jon Skeet에 따라 링크를 클릭합니다.

delegate void UInt32ParameterDelegate(UInt32 n); 

    public void UpdateLocation(UInt32 n) 
    { 
    if (InvokeRequired) 
    { 
     // We're not in the UI thread, so we need to call BeginInvoke 
     BeginInvoke(new UInt32ParameterDelegate(UpdateLocation), new object[] { n }); 
     return; 
    } 
    // Must be on the UI thread if we've got this far 

    this.engine.location.UpdateBusy.WaitOne(); 
    // do the work in here 

    this.engine.location.UpdateBusy.ReleaseMutex(); 

    } 
+0

.net 2.0을 사용하고 있습니까? – JoshBerke

답변

3

Windows Forms에서 동기화가 매우 쉽습니다. Control.Invoke() 백그라운드 스레드에서 호출 할 수 있습니다. 대리자가 UI 스레드에서 실행을 마칠 때까지 스레드가 정지합니다. 동기화가 필요하지 않습니다.

스레드를 멈추는 것이 문제가 있으면 Control.BeginInvoke()를 사용하십시오. 스레드가 계속 실행되는 동안 스레드가 스레드를 변경하면 잠금을 사용하여 대리인에게 전달한 객체를 보호해야합니다. 이것은 생산자 - 소비자 시나리오에서 거의 발생하지 않으며 스레드는 단순히 새 개체를 만들 수 있습니다.

너무 자주 Invoke()를 수행하지 마십시오.초당 약 1000 번 이상으로 자주 수행하며 UI 스레드는 Windows 메시지를 펌핑하는 것을 중지하고 호출 요청을 처리하여 속도가 느려집니다. 인간의 눈으로 기쁘게하려고하기 때문에 초당 약 25 회 이상 호출하는 것은 낭비입니다. 풀 중간 결과는 컬렉션 객체에 있습니다.

+0

+1 Windows Forms의 동기화에 대한 훌륭한 답변입니다. –

0

양식을 새로 고침하라는 이벤트를 발생시키는 대리인을 던지기가 쉽지 않을까요?

2

네트워크에서 GUI 스레드를 읽습니다. 네트워크 중단 중에 응용 프로그램이 실행되고 결과적으로 GUI가 중지되기까지는 시간 문제 일뿐입니다. 이것은 사용자를 정말로 좌절시킬 것입니다.

최상의 방법은 백그라운드 스레드가 읽기 작업을 완료하는 것입니다. 그런 다음 결과 데이터를 가져와 SynchronizationContext 게시 또는 전송 방법을 통해 GUI 스레드로 다시 이동하십시오.

3

문제를 올바르게 이해하기 바랍니다.

백그라운드 스레드가 데이터를 읽고 원하는대로 실행 한 후에는 Invoke을 사용하여 GUI 스레드에서 메소드를 호출해야합니다. 이 방법은 GUI에서 업데이트해야하는 모든 것을 업데이트합니다.

1

당신은 백그라운드 스레드에서 datareading를 처리하는 backgroundworker를 사용할 수 있으며, 당신이 일을 끝낼 때 당신이 RunWorkerCompletedEventHandler의 트리거 BackgroundWorker에를 종료 할 수 있습니다. RunWorkerCompletedEventHandler에서 GUI 스레드를 결과로 업데이트 할 수 있습니다.

관련 문제