2014-04-16 14 views
6

Sto configurando un worker in background per la prima volta. Funziona principalmente mentre il codice viene eseguito e il pulsante Stop/Annulla funziona. Tuttavia, sto anche cercando di segnalare i progressi per aggiornare una barra di avanzamento, ma non riesco a farlo sparare del tutto.Background Worker ReportProgress not firing

inizio il codice da un pulsante di scatto che viene eseguito questo codice:

backgroundWorker1.WorkerSupportsCancellation = true; 
backgroundWorker1.WorkerReportsProgress = true; 
backgroundWorker1.RunWorkerAsync();//this invokes the DoWork event 

mio metodo Do_Work:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      BackgroundWorker worker = sender as BackgroundWorker; 

      int j = 0;// Count cumulative imported files 
      int countDupFiles = 0;// Count number of previously imported csv files 
      int countImportedFiles = 0;// Count imported files 


      foreach (string folderPath in csvDirList) 
      { 
       string[] csvFileNames = Directory.GetFiles(@folderPath, "*.csv"); 
       frmImportCsvData.replaceAll(csvFileNames, folderPath + "\\", ""); 

       for (int i = 0; i < csvFileNames.Length; i++, j++) 
       { 
        string csvFilePath = folderPath + "\\" + csvFileNames[i]; 

        if ((worker.CancellationPending == true)) 
        { 
         e.Cancel = true; 
         break; 
        } 
        else 
        { 
         if (dataLayer.ImportCsvDataBkgrnd(this, csvFilePath, compIdValue, csvFileCount, i))//new method processes subdirectories if tick box selected 
         { 
          countImportedFiles = countImportedFiles + 1; 
         } 
         else 
         { 
          countDupFiles = countDupFiles + 1; 
         } 

         System.Threading.Thread.Sleep(500); 

        } 

        worker.ReportProgress(j);//tried using worker and backgroundWorker1 but neither works 
        backgroundWorker1.ReportProgress(j); 

        //string proj = j.ToString(); 
        //MessageBox.Show(proj);//Displays incrementing j as expected when not commented out 
       } 
      } 
      if (countImportedFiles > 0) 
       MessageBox.Show(countImportedFiles + " files were imported."); 
      if (countDupFiles > 0) 
       MessageBox.Show(countDupFiles + " files were not imported. Matches all ready in Database."); 
     } 

Cercando di sparare uno di questi eventi ProgressChanged:

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    string tbProgress = (e.ProgressPercentage.ToString() + "%"); 
    MessageBox.Show(tbProgress + "backgroundWorker1"); 
    importProgressBar(e.ProgressPercentage); 
} 

private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    string tbProgress = (e.ProgressPercentage.ToString() + "%"); 
    MessageBox.Show(tbProgress + "worker"); 
    importProgressBar(e.ProgressPercentage); 
} 

Infine, voglio che l'evento ProgressChanged attivi questo metodo per aggiornare la barra di avanzamento:

public void importProgressBar(int i) 
{ 
    progressTableLayoutPanel.Visible = true;//display progress bar 

    int percProgress = 100 * (i + 1)/csvFileCount; 

    if (percProgress <= 99)// Required to prevent values above 100 that crash the code 
     progressBar.Value = percProgress + 1;//hack that makes the progress bar update when progress value decreases 
    progressBar.Value = percProgress; 
    percProgressLabel.Text = percProgress.ToString(); 

    progressTableLayoutPanel.Update();//Required to display all progress bar table contents 
    //Thread.Sleep(200); 

    if (percProgress >= 100) 
    { 
     Thread.Sleep(200); 
     progressTableLayoutPanel.Visible = false; 
    } 
} 

L'annullamento codice del pulsante, che funziona, si presenta così:

private void stopImportButton_Click(object sender, EventArgs e) 
     { 
      backgroundWorker1.CancelAsync(); 
     } 

Le messageboxes nei miei eventi ProgressChanged mai mostrare su e la mia barra di progresso non è mai impostato su visibile. Qualche idea su quale potrebbe essere il problema?

risposta

7

Controllare questo esempio:

BackgroundWorker bgw = new BackgroundWorker();  
    public Form1() 
    { 
     InitializeComponent(); 
     label1.Text = ""; 
     label2.Text = ""; 
    } 

    private void button1_Click_1(object sender, EventArgs e) 
{ 
    if (bgw == null) 
    { 
     bgw = new BackgroundWorker(); 
     bgw.DoWork += new DoWorkEventHandler(bgw_DoWork); 
     bgw.ProgressChanged += new ProgressChangedEventHandler(bgw_ProgressChanged); 
     bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted); 
    } 
    bgw.WorkerReportsProgress = true; 
    bgw.WorkerSupportsCancellation = true; 
    bgw.RunWorkerAsync(); 
} 

    void bgw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     int total = 57; //some number (this is your variable to change)!! 

     for (int i = 0; i <= total; i++) //some number (total) 
     { 
      System.Threading.Thread.Sleep(100); 
      int percents = (i * 100)/total; 
      bgw.ReportProgress(percents, i); 
      //2 arguments: 
      //1. procenteges (from 0 t0 100) - i do a calcumation 
      //2. some current value! 
     } 
    } 

    void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     progressBar1.Value = e.ProgressPercentage; 
     label1.Text = String.Format("Progress: {0} %", e.ProgressPercentage); 
     label2.Text = String.Format("Total items transfered: {0}", e.UserState); 
    } 

    void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     //do the code when bgv completes its work 
    } 
} 

Forse questo ti aiuta con il tuo problema ...

e cercare di mettere i progressi di visibili solo dopo aver chiamato il background.doWork in caso pulsante di scatto .

+0

Stavo usando il componente backgroundworker dalla casella degli strumenti. Ma impostandolo manualmente come nel tuo esempio, ho capito tutto per funzionare. Grazie –

+1

prego :) –

+0

Ho trovato un bug. Se ho eseguito il mio processo di importazione più di una volta, è stato creato un ulteriore worker in background e quindi nella seconda esecuzione, tutto il codice è stato eseguito due volte, il terzo è stato eseguito 3 volte, ecc. L'istruzione if (bgw = null) impedisce la creazione di più bgw. –