1

여기의 문제는 약간 추상적입니다. 우리는 백그라운드 UI가 일부 UI 요소를 업데이트하기 위해 모든 것을 알고 있습니다.여러 배경 스레드에서 UI 업데이트

Dispatcher.Invoke() 

이 유일한 옵션입니까? 그러나 Dispatcher.Invoke() 자체는 업데이트 작업을 UI 스레드에 위임합니다. 시나리오 고려 대상 :

  • 백그라운드 스레드가 UI를 너무 자주 업데이트합니다.
  • 수십 개의 스레드가 동일한 UI를 업데이트합니다.

Dispatcher 개체는 업데이트 작업을 UI 스레드에 위임 할 때 계속해서 UI 스레드가 느려질 수 있습니다. 가능한 해결책은 무엇입니까? Windows Forms에서 이러한 문제를 어떻게 해결할 수 있습니까? 스레딩 모델은 WPF와 매우 비슷합니까? WPF는 다른 스레드 기술을 제공합니까? 빠른 그들이 처리 할 수있는 것보다, 다음 WPF에 상관없이/양식/무엇이든 문제가 없을 것입니다

관해서는, 당신은 메시지를 게시하여 GUI 스레드의 입력 큐에 과부하 경우

답변

1

첫 번째 이유는 인간의 눈이 자주 눈치 채지 못하는 UI를 업데이트해야하는 이유입니다. 어떤 진행 상황이 초 단위로 업데이트 되더라도 이상적입니다. 예를 들어 파일을 쓰고 있고 30 밀리 초마다 4K 바이트를 쓰고 있다면 사람의 눈으로 알지 못하며 밀리 초 단위로 화면의 성능에 신경 쓰지 않아도됩니다

UI 스레드는 사용하지만 Dispatcher는 사용할 수 없습니다. Invoke는 실행까지 다른 스레드를 차단합니다. Dispatcher.BeginInvoke가 다른 스레드를 차단하지 않습니다.

UI 스레드가 레이블 또는 화면의 진행률을 거의 업데이트하지 않으면 스레드가 업데이트를 완료하는 데 아마 몇 밀리 초가 걸릴 것입니다.

UI가 매우 복잡하고 여러 스레드로부터의 액세스를 허용하면 데드락이 자주 발생하여 응용 프로그램이 응답하지 않을 수 있기 때문에 WPF 나 다른 플랫폼에서 더 좋은 방법을 제공 할 수 없습니다. 모든 플랫폼, Java, objective-c 또는 모든 UI 프레임 워크가 UI의 작성자 스레드에서만 UI를 업데이트해야하는 이유입니다.

그러나 WPF에는 창당 여러 UI 스레드를 만들 수있는 방법이 있지만 매우 복잡합니다.게임 등에서는 이중 버퍼링을 사용합니다. 이중 버퍼링은 별도의 스레드에서 백그라운드에서 한 버퍼에서 작업하며 이전 버퍼는 화면에서 계속 업데이트됩니다.

+0

. "그러나 WPF에는 창당 여러 개의 UI 스레드를 만들 수있는 방법이 있지만 매우 복잡합니다." 나는 그것이 제공하는 모든 위험을 이해하고, 내가 찾고있는 해결책이 될 수 있습니다. http://eprystupa.wordpress.com/2008/07/28/running-wpf-application-with-multiple-ui-threads/ 개념을 시작하기 위해 더 좋은 링크를 게시 할 수 있습니까? 고맙습니다. :) – James

2

(어떤 APC의 대의원).

여러 GUI 상태가 너무 자주 업데이트되어 모든 변경 사항이 큐에 과부하가 걸리고 사람이 읽을 수 없도록 너무 빠르게 변경되는 디스플레이가 발생하는 경우 비 GUI 스레드가 저장하는 것이 일반적입니다 공유 객체/s의 최신 데이터 및 GUI 스레드가보다 합리적인 간격으로 타이머를 사용하여 데이터를 표시합니다.

모든 데이터를 손실없이 표시해야하는 경우 (예 : GUI 메모 또는 HTML 렌더러가 모든 데이터를 표시해야하는 경우), 객체 풀을 통한 적절한 흐름 제어 및/또는 데이터의 지연 게시가 필요할 수 있습니다. 메시지 대기열 과부하.

'이 문제는 다소 추상적입니다.'- 추상이 아닙니다. 바쁜 앱으로이 문제를 여러 번 겪었습니다. 내 물건에, 장기간 입력 대기열 과부하 내 스레드 간 통신 풀에서 모든 개체 처리되지 않은 게시 된 메시지 및 GUI 풀이 때문에 풀 릴리스 된 걸릴 때문에 교착 상태가 발생하는 경향이 있습니다 - 개체를 얻으려고 빈 풀에서 : (

+0

실제로 Invoke를 선택하면됩니다. 대기열을 막히는 경향이있는 BeginInvoke입니다. 귀하의 회신에 감사드립니다. –

1

간편한 UI를 업데이트하려면 Invoke을 사용하지 마십시오. 대신, 작업자 스레드가 "UI 스레드로 보낼"필요가있는 데이터를 큐 또는 목록 같은 공유 데이터 구조에 게시하고 UI 스레드가 특정 간격으로 폴링하도록하십시오. 이것은 몇 가지 장점이 있습니다.

  • Invoke이 부과하는 작업자 스레드와 UI 간의 긴밀한 연결이 끊어집니다.
  • UI 컨트롤이 업데이트 될 때 UI 스레드가 지시합니다. 실제로 생각할 때 UI 컨트롤이 있어야합니다.
  • Invoke 또는 BeginInvoke이 작업자 스레드에서 사용 된 경우와 같이 UI 메시지 대기열을 초과하거나 다른 메시지를 보급 할 위험이 없습니다.
  • 작업자 스레드는 Invoke의 경우와 같이 UI 스레드의 응답을 기다릴 필요가 없습니다.
  • UI 및 작업자 스레드 모두에서 처리량이 증가합니다.
  • InvokeBeginInvoke은 값 비싼 연산입니다.

나는이 모든 경우에 대해 수확기를 알고 있지만 실제로 많은 경우에 Invoke에 대한 더 나은 대안이 있습니다. Invoke 같은 마샬링 기술은 way 남용입니다.

관련 문제