2009-07-07 2 views
1

ListView (resultsList)가있는 WPF 폼이 있고 페이징을 통해 웹 페이지를 통해 일부 정보를 검색 한 결과를 반환하는 정적 메서드 Fetcher가 있습니다 (모든 페이지 한 번에 또는 각 페이지에 대해 하나의 수익). WebClient를 사용하여 40 개의 사이트를 가져 오는 데 약 2 분이 걸립니다. 검색이 끝난 직후에 결과를 표시하고 싶지는 않지만 수집 된 결과 목록에 표시하려고합니다. 따라서 부품별로 유용한 정보가 있으면 사용자가 검색을 중지 할 수 있습니다. 그것은 Windows에서의 검색과 같습니다. 결과는 한 번에 모두 발견되는 것이 아니라 지속적으로 나타납니다.다른 스레드에서 검색 결과가 부분적으로 실행되는 목록 업데이트

저는 멀티 스레딩 응용 프로그램에서 상당히 일반적인 문제라고 생각합니다. 극복하지 못했습니다.

답변

2

배경 작업자가 필요합니다. 아래, LoadChunk 프로 시저가 병렬 스레드에서 호출되지만 ChunkLoaded가 주 스레드에서 호출되므로 LoadChunk의 임시 목록에 결과가 누적되지만 WorkProcessor에서 ReportProgress를 호출하면 주요 UI 바인딩 된 콜렉션을 채울 수 있습니다 임시 목록에서.

public void LoadDataAsync() 
    { 
     ... 
     BackgroundWorker bw = new BackgroundWorker(); 
     bw.WorkerReportsProgress = true; 
     bw.DoWork += LoadChunk; 
     bw.ProgressChanged += new ProgressChangedEventHandler(ChunkLoaded); 
     bw.RunWorkerAsync(); 
    } 

    void ChunkLoaded(object sender, ProgressChangedEventArgs e) 
    { 
     PopulateDataToUI(); 
    } 

    private void LoadChunk(object sender, DoWorkEventArgs e) 
    { 
     int chunkNum = 0; 
     BackgroundWorker bw = (BackgroundWorker)sender; 
     bw.ReportProgress(chunkNum++); 
     while (true) 
     { 
      ... 
      bw.ReportProgress(chunkNum++); 
      if (done) then break; 
     } 
    } 

편집 : 난 아무것도 고정하지 않습니다 - LoadChunk가 관찰 모음으로 개인 컬렉션에서 개인 수집 및 ChunkLoaded 전송으로 읽습니다. 이 개인 컬렉션을 사용하는 BackgroundWorker는 하나 뿐이지 만 충돌은 발생할 수 없습니다.

+0

고마워요! 나를 위해 매력처럼 작동합니다. 추가하는 것이 중요합니다. 어떻게 든 ChunkLoaded에 청크를 전달해야합니다. bw.ReportProgress (chunkNum ++, chunk)로 수행 할 수 없습니다. 그래서 UserState는 .NET에서 어떤 종류의 버그이고 ChunkLoaded의 userState는 항상 null입니다. 그래서 당신은 메인 쓰레드에 임시리스트를 생성하고, LoadChunk에서 잠그고, 채우고, 잠금 해제 한 다음 ChunkLoaded에서 사용해야합니다. 아니면 더 좋은 생각이 있습니까? –

관련 문제