Issues with BackgroundWorker and Progressbar C # Visual Studio 2010
I'm trying to get my head around the background worker and the progress bar while I have a job, but not quite the way I want it to work. Basically I am sorting / renaming the folders and copying them elsewhere, this works and the code explains itself, the output folders are generated as expected. However, for each folder I intend to execute, I have to right-click it to get the number of files, and then in code, I need to set progressBar1.Maximum to this value so that it displays the kernel progress in the progress bar, How can I get this to set the number of files automatically as it goes through each folder? Some folders have thousands of files and others have millions. Apart from that, I want to add a label so that it displays the name of the file being processed along with the progressbar updates.
namespace Data_Sorter
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnSelect_Click(object sender, EventArgs e)
{
folderBrowserDialog1.ShowDialog();
tbFilePath.Text = folderBrowserDialog1.SelectedPath.ToString();
}
private void btnSort_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int totalFiles = 0;
foreach (var file in Directory.GetFiles(tbFilePath.Text, "*.txt", SearchOption.AllDirectories))
{
backgroundWorker1.ReportProgress(totalFiles);
string fullFilename = file.ToString();
string[] pathParts = fullFilename.Split('\\');
string date = pathParts[6];
string fileName = pathParts[7];
string[] partName = fileName.Split('_');
string point = partName[3];
Directory.CreateDirectory("Data Sorted Logs\\" + point + "\\" + date + "\\");
if (Directory.Exists(("Data Sorted Logs\\" + point + "\\" + date + "\\")))
{
string destPath = (point + "\\" + date + "\\");
File.Copy(fullFilename, "C:\\Documents and Settings\\PC\\Desktop\\Sorter\\Data Sorter\\bin\\Debug\\Data Sorted Logs\\" + destPath + fileName); }
else
{
MessageBox.Show("destination folder not found " + date + point);
}
totalFiles++;
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Done");
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Maximum = 6777; // set this value at the maximum number of files you want to sort //
progressBar1.Value = e.ProgressPercentage;
}
}
source to share
You can find out the file number by simply reading the length of GetFiles.
You can pass a relative percentage using the expression:, (i * 100) / totalFiles
so there is no need to set a maximum value for progress.
You can also provide the name of the file to the progress bar by passing it as UserState in the progressChanged event.
Try the code below:
namespace Data_Sorter
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnSelect_Click(object sender, EventArgs e)
{
folderBrowserDialog1.ShowDialog();
tbFilePath.Text = folderBrowserDialog1.SelectedPath.ToString();
}
private void btnSort_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int totalFiles = 0;
string[] files = Directory.GetFiles(tbFilePath.Text, "*.txt", SearchOption.AllDirectories);
totalFiles = files.Length;
int i = 0;
foreach (var file in files)
{
backgroundWorker1.ReportProgress((i * 100) / totalFiles, file);
i++
string fullFilename = file.ToString();
string[] pathParts = fullFilename.Split('\\');
string date = pathParts[6];
string fileName = pathParts[7];
string[] partName = fileName.Split('_');
string point = partName[3];
Directory.CreateDirectory("Data Sorted Logs\\" + point + "\\" + date + "\\");
if (Directory.Exists(("Data Sorted Logs\\" + point + "\\" + date + "\\")))
{
string destPath = (point + "\\" + date + "\\");
File.Copy(fullFilename, "C:\\Documents and Settings\\PC\\Desktop\\Sorter\\Data Sorter\\bin\\Debug\\Data Sorted Logs\\" + destPath + fileName); }
else
{
MessageBox.Show("destination folder not found " + date + point);
}
totalFiles++;
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Done");
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
progressBar1.Text = e.UserState.ToString();//or yourNewLabel.Text = e.UserState.ToString();
}
}
source to share
Move the call to GetFiles so you can get the length of the returned array:
string[] files = Directory.GetFiles(tbFilePath.Text, "*.txt",
SearchOption.AllDirectories));
// Note - you won't be able to set this UI property from DoWork
// because of cross-thread issues:
// progressbar1.Maximum = files.Length;
int fileCount = files.Length;
foreach (var file in files ...
source to share