2011-09-19 6 views
0

TabItem을로드 할 때 (각 TabItem이 ViewModel에 바인딩되고 각 ViewModel에 DataTemplate이 있음) 내 응용 프로그램에 성능 문제가 있습니다. 이 문제를 해결하기 위해, 내가있는 ViewModel 생성자에서 비동기로드 사용이 솔루션을비동기식 첫 번째 성능 문제 TabItem로드

public MyViewModel(MyObject entity) 
    { 
     // WpfContext it's my Dispatcher 
     Task.Factory.StartNew(() => WpfContext.Invoke(() => 
            { 
             //Initialisation 
             LoadMyObject(entity); 
            })); 
    } 

을의 TabItem에로드되는 첫 번째 시간, 일부 시간을 소요하고 정말 비동기없는 것 같다. 다른로드에서는 잘 작동하고 비동기 적으로 작동합니다. 나는 이유를 정확히 모른다. 어떠한 제안 ?

답변

1

Invoke은 Dispatcher의 백그라운드 스레드와 UI 스레드 (실제로 코드를 실행하기로 결정한)에 대한 블로킹 호출입니다.

UI 스레드가 새 탭을 표시 중이므로 백그라운드 스레드의 Invoke이 UI 스레드에 처리 할 때까지 비동기 적으로 표시되는 경우가 있습니다. 동기화 된 것처럼 보이면 전에 UI 스레드 에 의해 Invoke 호출이 처리되고 있습니다. 새 탭이 표시됩니다. 결국, 당신은 경쟁 조건을 가지고 있다고 생각합니다.

이 문제를 해결하려면 배경 스레드에서 실행할 수 있도록 LoadMyObject 메서드를 리팩터링해야하거나 Dispatcher.BeginInvoke 메서드를 사용하고 낮은 우선 순위를 지정하여 새 탭의 표시가 처리를 앞당길 수 있도록해야합니다 LoadMyObject 호출

+0

"당신의 LoadMyObject를 리팩터링해야 할 수도 있습니다"라는 말은 정확히 무슨 뜻입니까? Task.Factory.StartNew를 사용하여 LoadMyObject를 호출하는 백그라운드 작업을 만들지 않았습니다. 아무 것도 변경되지 않았습니다 ... BeginInvoke를 시도했지만 TabItem이 비어 있습니다. – rad

+0

'LoadMyObject'가 실제로 무엇을하는지 모르겠으므로, 장시간 실행되는 메소드로 가정하여 WPF가 새 데이터를 렌더링하기 위해 디스플레이를 업데이트하도록 알려줍니다. 배경 스레드에서 오랫동안 실행되는 부분을 수행하도록 리팩터링 한 다음 필요한 경우에만 UI를 호출 할 수 있다고 생각했습니다. 지금 당장은 UI 스레드로 바로 돌아가는 Invoke를 즉시 호출하기 때문에 Task를 시작해도 아무 것도 바뀌지 않습니다. – davisoa