2011-01-21 23 views
1

嗨 我試圖整合與進度條後臺工作時,但不能得到正確實施ReportProgress。BackgroundWorker的進度 - 問題時,環另一類

我正在處理一些文件,所有的處理都是在外部類中完成的。

我的困難是,循環是這個班,在那裏通常我做的交談BackgroundWorker的內部。

的好處是在處理文件時,只要每個文件已完成處理的事件。

這是我的代碼如何實現這一目標

BackgroundWorker _bw = new BackgroundWorker 

    private void RunLongProcess() 
    { 
     _bw.WorkerReportsProgress = true; 
     _bw.WorkerSupportsCancellation = true;   
     _bw.DoWork += DoWork; 
     _bw.ProgressChanged += ProgressChanged; 
     _bw.RunWorkerCompleted += RunWorkerCompleted; 

     _bw.RunWorkerAsync();//start the process 

     if (_bw.IsBusy) 
      _bw.CancelAsync(); 
    } 

    static void DoWork (object sender, DoWorkEventArgs e) 
     {  

     var files=GetFiles(); 
     int fileCount=files.Count; 

     //usually I do a loop here but all the processing is done inside this class so 

     var fileProcessor=new FileProcesser(); 
     fileProcessor.ProcessFiles(files);   

     } 
    private void OnFileProcessCompleted(object sender, FileEventArgs e) 
    { 
     //Event Fired when a file has been processed 
     //How do I update progressBar.Problem cross threading here. 

         //What do I do here????? 
     _bw.ReportProgress(e.FileProcessedCount, e); 
    } 

    ProgressChanged (object sender, ProgressChangedEventArgs e) 
    { 
      // Update the UI 
     labelProgress.Text = e.UserState; 
     progressBar.Value = e.ProgressPercentage; 
    } 


    private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     if (e.Cancelled) 
      // Console.WriteLine("You canceled!"); 
     else if (e.Error != null) 
      //Console.WriteLine("Worker exception: " + e.Error.ToString()); 
     else 
      // Console.WriteLine("Complete: " + e.Result); 
    } 

回答

2

_bw.ReportProgress(e.FileProcessedCount, e);不應OnFileProcessCompleted去。此事件在DoWork完成時觸發。你應該把它放在DoWork來更新進度條。因此,這將是這個樣子:

private void DoWork (object sender, DoWorkEventArgs e) 
{  
    BackgroundWorker bg = sender as BackgroundWorker; 

    var files = GetFiles(); 
    int fileCount = files.Count; 

    var fileProcessor = new FileProcesser(); 
    for(int i = 0; i < fileCount; i++) 
    { 
     fileProcessor.ProcessFile(files[i]); 
     bg.ReportProgress((uint)((i/(double)fileCount) * 100)); 
    } 
} 

我將在BackgroundWorker的傳遞給FileProcessor這樣的:

private void DoWork (object sender, DoWorkEventArgs e) 
{ 
    BackgroundWorker bg = sender as BackgroundWorker;  
    var files = GetFiles(); 
    int fileCount = files.Count; 
    var fileProcessor=new FileProcesser(bg); 
    fileProcessor.ProcessFiles(files);   
} 

在FileProcesser,它會是這個樣子:

private BackgroundWorker _bg; 
public FileProcessor(BackgroundWorker bg) 
{ 
    _bg = bg; 
} 

public void ProcessFiles(Files files) 
{ 
    // Process files 
    // ... 
    // Report Progress 
    _bg.ReportProgress(e.FileProcessedCount, e); 
} 
+0

不是這樣,當`DoWork`完成時``RunWorkerCompleted`被觸發。它看起來像`OnFileProcessCompleted`是'fileProcessor`提出的事件 – Aphex 2011-01-21 20:24:17

0

在這種情況下,任何的建議,一個解決方案是一個派生類BackgroundWorker,使其訂閱該事件,並將它發送進度事件發送到事件處理程序中的UI線程。