2012-10-02 2 views
1

이 질문이 약간 일반적인 경우 사과드립니다. 난 그냥이 문제를 해결하는 방법에 대한 몇 가지 일반적인 조언을 찾고 있어요 :)저장소에서 항목을 검색 할 때 GridView를 비동기 적으로 채우는 방법

지금 나는 사용자 정의 FileService에있는 파일의 목록을 검색하고 다음 비동기 메서드가 있습니다. 이 문제는 ViewModel의 생성자에서 발생합니다.

private async void Construct() 
{ 
    Files = new ObservableCollection<FileViewModel>(); 
    IList _files = await _fileRepository.GetFiles(); 
    foreach (File file in _files) 
    { 
     Files.Add(new FileViewModel(file)); 
    } 
} 

당신은 아마 해결할 수 있듯이

는 비동기 방법은 1 단계에서 파일 목록을 검색 한 다음이를 다른 (UI에 바인딩 소스 인) 목록에 추가됩니다.

사용자는 비동기 프로세스가 끝날 때까지 아무 것도 볼 수 없으며 잠시 후 모든 결과를 한 번에 볼 수 있습니다.

내 머리 속에서는 비동기식 점을 무너 뜨려서 실제로 검색된 결과가 추가되고 싶습니다.

또 다른 단계를 추가하려면 각 파일의 첫 글자를 범주로 그룹화하는 linq 쿼리가 있어야합니다. 이것은 foreach 루프 이후에 실행됩니다. 이 단계를 추가하면 어떻게 될까요?

주셔서 감사합니다.

답변

2

이렇게하려면 저장소를 기본 수준에서 변경해야합니다. 항목을 검색 할 때 이벤트를 발생시키는 개체를 반환 할 수 있으며 이벤트 처리기에서 컨트롤이 바인딩 된 INotifyCollectionChanged interface 구현에 개체를 추가 할 수 있습니다.

또한 Reactive Extensions을 살펴보고 구독하면 INotifyCollectionChanged을 구현하는 데이터 소스에 항목을 추가하는 IObservable<T> interface 구현을 노출 할 수 있습니다.

어떤 방법을 사용하든 관계없이 UI 구성 요소는 UI 스레드 호출을 마샬링해야한다는 의미에서 UI 구성 요소가 작성된 스레드에서만 업데이트된다는 사실을 고려해야합니다.

가장 쉬운 방법이 당신이 INotifyCollectionChanged 구현에 상품을 추가하기 위해 전화로 Post method를 호출 한 후 비동기 전화를 걸 전에 static Current property를 사용하여 SynchronizationContext 캡처 할 수 있습니다.

async/await이 상황에서는 실제로 사용할 수 없습니다. 작업이 완료 될 때 알림에는 적합하지 않지만 작업이 완료되면 비동기 작업에 대해 계속 작업을 수행해야합니다.

이러한 접근법을 다시 생각해 볼 수 있습니다. 대부분의 LINQ 공급자의 경우 에서 파생 된 IQueryable<T>이 반환됩니다. IEnumerable<T>이 반복되는 동안 확실히 차단할 수 있지만 대부분의 공급자는 결과를 빠른 연속으로 스트리밍하므로 원하는 효과를 내기에는 너무 빠릅니다.

LINQ 공급자 입니다 너무 느리게 (각각의 반복 사이에 큰 격차)를 제공하는이, 당신은 당신에 배치 할 항목을 제공하기 위해 위에서 언급 한 패턴 중 하나를 사용하려면 반응성 프레임 워크에 ToObservable extension method를 사용할 수있는 경우

당신의 당신이 그 (것)들을 얻을하자마자 명부.

1

이렇게하려면 파일 저장소를 변경해야합니다.

TPL 데이터 흐름을 사용하는 것이 좋습니다. 파일 저장소가 채우기를 시작할 BufferBlock<File>을 노출시키고 코드에서이를 소비하도록하십시오.

관련 문제