2014-12-09 3 views
1

다른 그리드에 대한 벤치마킹을 벤치마킹하려는 시나리오를 발견 할 때까지 스레딩에 대해 잘 알고 있다고 생각했습니다.백그라운드에서 목록을 업데이트 할 때 UI 스레드가 멈추는 이유는 무엇입니까?

그리드 컨트롤이있는 창을 만들고 ObservableCollection에 바인딩하고 5000 개의 행에 몇 가지 복잡한 데이터 유형 (잠금이 없음)을 채 웁니다.

은 그 때 나는 그 각각은 물론의 INotifyPropertyChanged 이벤트를 발생, 내 ObservableCollection에서 임의의 항목에 임의의 속성을 업데이트

Task.Factory.StartNew() 

이 아주 꽉 루프를 통해 갔다 (1000 만 반복)를 사용하여 작업을 생성 .

배경 스레드에서 업데이트가 모두 발생했기 때문에 UI가 업데이트 될 것으로 예상했지만, 백그라운드 스레드가 빡빡한 루프에서 돌아가는 것을 견디기는 힘들지만 말입니다.

대신에 UI는 몇 초 동안 얼었지만 (공백이 생기지 않았거나 운명의 일반적인 회전 커서가 생성되지 않음) 배경 스레드가 완료되면 돌아 왔습니다.

내 이해는 UI 스레드에 WPF 런타임에 의해 자동으로 마샬링되는 수많은 INPC를 생성하면서 백그라운드 스레드가 코어에 과도하게 부담을 줄 것이라고 생각했습니다.

이제 UI 스레드가 아무 것도하지 않아서 모든 INPC를 소비하고 그리드를 업데이트 할 것으로 예상했지만 그렇지 않았습니다. 단일 업데이트가 발생하지 않았습니다. 그러나, 타이머 (단단한 루프 대신)를 사용하여이 작업을 수행하면 정상적으로 작동합니다.

누군가가 UI 스레드가 무슨 일을하고 있는지 알려주시겠습니까? 미리 감사드립니다!

+3

이 문제를 보여주는 가장 짧은 코드 예를 제공 할 수 있습니까? –

+1

"tight loop"란 각 반복마다 지연이 없음을 의미합니까? UI가 유지할 수없는 업데이트로 포격당하는 간단한 경우 인 것 같습니다. – McGarnagle

답변

1

이와 같이 많은 디스패치 된 업데이트로 메시지 펌프가 막히면 다른 메시지가 처리되지 않아 '고정'효과가 발생합니다.

여기에서 도움이 될 수있는 한 가지는 UI 컨트롤에서 데이터 가상화를 사용하여 보이는 행만 실제로 바인딩되고 INPC 업데이트를 수신하는 것입니다. 이 기능은 기본적으로 DataGrid에 사용하도록 설정되어 있지만 데이터를 시각화하는 데보다 맞춤화 된 방법을 사용하는 경우 문제가 될 수 있습니다.

그렇다고해서 현재 표시되는 항목을 자주 수정하는 데 도움이되지 않습니다. 정말 빠른 화재 업데이트로 인해 운영자가 계속 혼란에 빠질 수 있습니다. 이런 유스 케이스가 있다면, 뷰 모델 객체를 약간 분리하고 업데이트를 '배치'하는 방법을 원할 것입니다. 한 가지 방법은 업데이트를 수행하는 동안 알림을 표시하지 않도록 설정 한 다음 각 인스턴스에 RaisePropertyChanged(null) (또는 INPC 도우미 기본 클래스의 해당하는 메서드)을 호출하여 해당 인스턴스에 대한 모든 바인딩을 업데이트하는 것입니다.

다른 메커니즘 (보기 모델 인스턴스가 나타내는 모델 객체와 상관없이)에서 다른 데이터를 업데이트 한 다음 잘 정의 된 간격으로 해당 속성을 뷰 모델 클래스에 복사하는 것입니다. 백그라운드 데이터를 빠르게 업데이트하기 위해 이벤트를 트리거하는 것보다는 폴링 루프를 사용하는 경우가 종종 있습니다. 이는 UI가 신경 쓰는 것보다 이벤트가 더 자주 발생하고 이러한 불필요한 알림을 지속적으로 보내는 백그라운드 처리 속도가 느려지 기 때문입니다.

+0

고마워 Bryant; 당신 (또는 알고있는 누군가)은 그동안 메시지 펌프가하는 일을 정확히 설명 할 수 있습니까? 왜 디스패처가 "막히지"? 예를 들어 UI 스레드이고 사용자가 작업자이고 처리 할 수있는 것보다 빠르게 업데이트를 생성한다고 가정 해 보겠습니다. 우리는 여전히 완전히 독립적 인 쓰레드로 병렬 작업을하고 있습니다. 그래서 당신이 생산하는 100 개의 업데이트를 10 개를 처리 할 수 ​​있어야합니다. 나는 뒤에서 지체 할 것이지만 나는 여전히 일을해야하고 유휴 상태로 보이지 않아야한다. – Anthony

+0

@Anthony, 좀 복잡하지만 제 이해는 데이터 바인딩이 상대적으로 높다는 것입니다 [DispatcherPriority] (http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherpriority%28v= vs.110 % 29.aspx) 이는 전달 된 알림 큐가 처리되어 다른 방식으로 처리되기를 원하는 다양한 메시지보다 우선적으로 서비스된다는 것을 의미합니다. 따라서 응용 프로그램이 실제로 교착 상태에 빠지는 것은 아니지만 실제로 제한된 응답 성을 제공 할 수도 있습니다. –

+0

특히 'Input'및 'Render'메시지는 모두 'DataBinding'보다 우선 순위가 낮으므로 응용 프로그램이 입력에 응답하지 않고 렌더링 된 출력을 업데이트하지 않지만 실제 Windows 처리기는 여전히 처리 중입니다.), 그래서 마지막으로 캐시 된 렌더링 된 출력물과 함께 Window가 계속 표시됩니다. –

관련 문제