2014-12-17 3 views
0
WPF 응용 프로그램에서

안 상태 (C 번호는 .NET 4.0 2013 VS) (UI 스레드로 불림)는 다음 코드는 1 초 UI 스레드를 정지 :UI 스레드 정지가

new Thread(new ThreadStart(() => 
{ 
    Dispatcher.BeginInvoke(new Action(() => 
    { 
     Thread.Sleep(1000); 
    })); 
})).Start(); 

Thread.Sleep()은 자리 표시 자입니다. 실제 코드에서는 일부 UI 요소에 액세스하고 시간을 많이 소비하는 계산을 수행합니다. 그것도 UI 스레드에서 실행됩니다!

UI 스레드가 아닌 다른 스레드에서 실행하면 안됩니까? 나는 무엇을 놓쳤는가?

+0

Dispatcher를 사용하여 UI 스레드에서 작업을 실행하면 잠시 차단됩니다. – Samuel

+0

백그라운드 스레드에서 UI에 액세스하면 예외가 발생합니다. UI 요소에 대한 업데이트는 주 스레드에서 수행해야하며 Dispatcher.BeginInvoke (...)를 사용할 수 있습니다. – Onots

답변

4

Dispatcher.BeginInvoke은 (위임을 통해) UI 스레드로 작업을 푸시 ()하도록 설계되었습니다. 이라고 말하면 Thread.Sleep(1000)을 UI 스레드로 푸시해야합니다. 예 : UI 스레드가 멈 춥니 다.

From MSDN

예를 들어

, UI 스레드에서 만든 버튼의 내용을 업데이트 할 수 없습니다 메인 UI 스레드에서 분사되는 백그라운드 스레드. 백그라운드 스레드가 Button의 Content 특성에 액세스하려면 백그라운드 스레드가 UI 스레드와 연관된 Dispatcher로 작업을 위임해야합니다. 이것은 Invoke 또는 BeginInvoke를 사용하여 수행됩니다. 호출은 동기식이며 BeginInvoke는 비동기식입니다.

당신이 백그라운드에서 작업을하고 싶었다면

... 당신은 (Dispatcher.BeginInvoke를 호출하기 전에) 백그라운드 스레드에 이미 있었다.

  1. 사용 .Invoke은을 업데이트
  2. 작업자에 사용 .Invoke 또는 .BeginInvoke을 처리 할 작업자
  3. 로 UI에서 값을 수집합니다 :

    나는 당신이 여기 일을해야하는 것은 의심 UI

+0

감사합니다. 나는 Dispatcher.BeginInvoke/Invoke의 목적을 잊어 버리는 경향이있다. :( – Donotalo

1

Dispatcher.BeginInvoke는 주 스레드에서 작업을 실행합니다. 스레드에서 실행하려면이 옵션을 사용

new Thread(new ThreadStart(() => 
    { 
     { 
      Thread.Sleep(1000); 
     }; 
    })).Start(); 
1

마크는 이미 당신이 당신의 UI가 반응 유지하려는 경우 코드가 실행됩니다 있도록 Dispatcher.BeginInvoke()는 UI 스레드로 동작 INT 모든 코드를 밀어 말했듯 Dispatcher.Begin을 호출하기 전에 계산을 수행하고 BeginInvoke에서 UI 컨트롤을 설정하십시오.

new Thread(new ThreadStart(() => 
{ 
    int result = MyHeavyCalculation(); 
    Dispatcher.BeginInvoke(new Action(() => 
    { 
     label1.Text = result.ToString(); 
    })); 
})).Start(); 

또는 방법의 asynchron을 실행하고 UI는 자신을 threadsynchronization 귀찮게 해달라고 async-await를 보라. Simple Example