2012-11-12 2 views
0

DataGridObservableCollection 소스에 바인딩하여 파일 분석시 얻은 두 개의 열, 파일 이름 및 번호를 표시합니다.백그라운드 스레드에서 C# DataGrid 새로 고침

ObservableCollection<SearchFile> fileso; 

    //... 

    private void worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     /* Get all the files to check. */ 
     int dirCount = searchFoldersListView.Items.Count; 
     List<string> allFiles = new List<string>(); 
     for(int i = 0; i < dirCount; i++) 
     { 
      try 
      { 
       allFiles.AddRange(Directory.GetFiles(searchFoldersListView.Items[i].ToString(), "*.txt").ToList()); 
       allFiles.AddRange(Directory.GetFiles(searchFoldersListView.Items[i].ToString(), "*.pdf").ToList()); 
      } 
      catch 
      { /* stuff */ } 
     } 

     /* Clear the collection and populate it with unchecked files again, refreshing the grid. */ 
     this.Dispatcher.Invoke(new Action(delegate 
     { 
      fileso.Clear(); 
      foreach(var file in allFiles) 
      { 
       SearchFile sf = new SearchFile() { path=file, occurrences=0 }; 
       fileso.Add(sf); 
      } 
     })); 

     /* Check the files. */ 
     foreach(var file in allFiles) 
     { 
      this.Dispatcher.Invoke(new Action(delegate 
      { 
       int occurences; 
       bool result = FileSearcher.searchFile(file, searchTermTextBox.Text, out occurences); 

       fileso.AddOccurrences(file, occurences); // This is an extension method that alters the collection by finding the relevant item and changing it. 
      })); 
     } 
    } 

    //... 

    public static void AddOccurrences(this ObservableCollection<SearchFile> collection, string path, int occurrences) 
    { 
     for(int i = 0; i < collection.Count; i++) 
     { 
      if(collection[i].path == path) 
      { 
       collection[i].occurrences = occurrences; 
       break; 
      } 
     } 
    } 

    //... 

    public static bool searchTxtFile(string path, string term, out int occurences) 
    { 
     string contents = File.ReadAllText(path); 
     occurences = Regex.Matches(contents, term, RegexOptions.IgnoreCase).Count; 
     if(occurences>0) 
      return true; 
     return false; 
    } 

    public static bool searchDocxFile(string path, string term, out int occurences) 
    { 
     occurences = 0; 

     string tempPath = Path.GetTempPath(); 
     string rawName = Path.GetFileNameWithoutExtension(path); 
     string destFile = System.IO.Path.Combine(tempPath, rawName + ".zip"); 
     System.IO.File.Copy(path, destFile, true); 

     using(ZipFile zf = new ZipFile(destFile)) 
     { 
      ZipEntry ze = zf.GetEntry("word/document.xml"); 
      if(ze != null) 
      { 
       using(Stream zipstream = zf.GetInputStream(ze)) 
       { 
        using(StreamReader sr = new StreamReader(zipstream)) 
        { 
         string docContents = sr.ReadToEnd(); 
         string rawText = Extensions.StripTagsRegexCompiled(docContents); 
         occurences = Regex.Matches(rawText, term, RegexOptions.IgnoreCase).Count; 
         if(occurences>0) 
          return true; 
         return false; 
        } 
       } 
      } 
     } 
     return false; 
    } 

    public static bool searchFile(string path, string term, out int occurences) 
    { 
     occurences = 0; 
     string ext = System.IO.Path.GetExtension(path); 

     switch(ext) 
     { 
      case ".txt": 
       return searchTxtFile(path, term, out occurences); 
      //case ".doc": 
      // return searchDocFile(path, term, out occurences); 
      case ".docx": 
       return searchDocxFile(path, term, out occurences); 
     } 
     return false; 
    } 

그러나 문제는 내가 (위하여 do_work 방법으로 근로자를 시작합니다) 업데이트 버튼을, 시간의 일부를 명중 할 때 때때로, 나는 숫자 열 대신에 임의 제로를 얻고 있다는 것입니다 올바른 번호. 왜 그런가요? 숫자 열을 두 번 업데이트 할 때 몇 가지 문제가 있기 때문에 실제 업데이트 후에 적용되는 경우가 종종 있지만 처음에는 제로가 적용되지만 세부 사항은 확실하지 않기 때문입니다.

+0

.Net> 2.0을 타겟팅하는 경우 람다 구문 (=>)으로 변경하려고합니다. 둘째, 파일별로 작업을 생성해서는 안됩니다. 오히려 전체 수집을위한 한 가지 방법이 있습니다. 또한 파일은 무엇입니까? –

+0

당신이 제공 한 예제에서보기가 어렵지만, 동기 인 Disptacher.Invoke를 사용하기 때문에 열이 두 번 업데이트되고있는 것 같지는 않습니다. AddOccurrences 확장 메서드와 SearchFile 구현을 게시 한 경우 도움이 될 것입니다. – bryanbcook

+0

좋아요, 메소드 코드를 추가했습니다. –

답변

1

나는 기본적으로 어떤 일어나고있는 것은 당신이 람다 식에 파일 변수를 전달하는 것입니다,하지만 작업이 실제로 전에 파일이 foreach 루프에 의해 수정 될 것 이것이 access to a modified closure

 /* Check the files. */ 
     foreach(var file in allFiles) 
     { 
      var fileTmp = file; // avoid access to modified closure 
      this.Dispatcher.Invoke(new Action(delegate 
      { 
       int occurences; 
       bool result = FileSearcher.searchFile(fileTmp, searchTermTextBox.Text, out occurences); 

       fileso.AddOccurrences(fileTmp, occurences); // This is an extension method that alters the collection by finding the relevant item and changing it. 
      })); 
     } 

의 경우라고 생각합니다 임시 변수를 사용하여 파일을 저장하면이 문제가 해결됩니다.

관련 문제