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?
Stavo usando il componente backgroundworker dalla casella degli strumenti. Ma impostandolo manualmente come nel tuo esempio, ho capito tutto per funzionare. Grazie –
prego :) –
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. –