2011-01-21 3 views
1

안녕 백그라운드 작업자를 진행률 막대와 통합하려고하지만 올바르게 처리 할 수 ​​없습니다.BackgroundWorker progressBar - 다른 클래스에서 루프가 발생하는 경우 ReportProgress 구현 문제가 발생했습니다.

일부 파일을 처리 중이며 모든 처리가 외부 클래스에서 수행됩니다.

필자의 어려움은 루핑이이 클래스의 내부에 있다는 것입니다. 일반적으로 나는 백그라운드 워커와 이야기하고 있습니다.

파일을 처리 할 때 각 파일이 처리를 완료 할 때마다 이벤트가 발생한다는 것이 좋습니다.

이이이이 경우

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에 입력해야합니다. 나는이 같은 FileProcessor에 BackgroundWorker에 전달할 것

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)); 
    } 
} 

: 그래서 이런 식으로 뭔가 보일 것

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

사실이 아니라면,'RunWorkerCompleted'는'DoWork'가 완료되었을 때 시작됩니다. 'OnFileProcessCompleted'는'fileProcessor'에 의해 발생한 이벤트입니다. – Aphex

+0

@Aphex - 네가 옳았다 고 생각합니다. 이 경우, OP는 BackgroundWorker bg를 FileProcessor로 전달하고 거기에서 ReportProgress를 호출해야합니다. 완료된 이벤트를 호출 할 필요가 없습니다. – SwDevMan81

0

을 달성 할 수있는 방법을 제안은, 하나 개의 솔루션은 BackgroundWorker에서 파생 클래스를 만들기는 이벤트에 가입 확인하고 진행을 보낼 것입니다 내 코드입니다 이벤트를 이벤트 핸들러의 UI 스레드에 전달합니다.

관련 문제