Progress Help
I am very new in programming and am still doing pretty well. But the progress indicators still confuse me. The Web, unfortunately, has many different examples for me to get something out of. Some say to use a background worker, some don't, etc. Below I have what I THINK should work, but not. Its just assumed that it works indicator when you copy a file from one folder to another. Any help is appreciated.
Thanks.
private void btnCopyFiles_Click(object sender, EventArgs e)
{
string folder1 = @"c:\folder1\";
string folder2 = @"c:\folder2\";
DirectoryInfo di = new DirectoryInfo(folder1);
FileInfo[] filelist = di.GetFiles("*.*");
int count = di.GetFiles("*.*").Length;
this.progressBar1 = new System.Windows.Forms.ProgressBar();
progressBar1.Maximum = count;
progressBar1.Minimum = 0;
progressBar1.Step = 1;
foreach (FileInfo file in filelist)
{
try
{
this.Cursor = Cursors.WaitCursor;
File.Copy(folder1 + @"\" + file.Name, folder2 + @"\" + file.Name, true);
progressBar1.PerformStep();
this.Cursor = Cursors.Default;
}
catch (Exception error)
{
MessageBox.Show("Error: " + error);
}
}
}
a source to share
I am assuming that you are using Visual Studio and added a ProgressBar control by dragging and dropping it onto the form. If this is correct, the following line may appear:
this.progressBar1 = new System.Windows.Forms.ProgressBar();
When you restore a control, you lose its link to the form. Just remove or comment this line and try again.
a source to share
In general, the problem is that your code continues to execute, preventing the form from re-drawing itself as it should. Your best and fastest route is to use the BackgroundWorker to actually execute your operation, using its events to update the progress. With this, updates to the execution line are done on the UI thread and UI updates, your file operations are done behind the scenes.
a source to share
First, create a structure to hold the BackgroundWorker arguments to be passed to the DoWorkEventArgs.
public struct CopyStruct
{
public string sourceDir;
public string destDir;
}
Then do something like this:
private void btnCopyFiles_Click(object sender, EventArgs e)
{
InitializeBackgroundWorker();
CopyStruct copyStruct = new CopyStruct
{
sourceDir = @"C:\folder1\",
destDir = @"C:\folder2\"
};
backgroundWorker.RunWorkerAsync(copyStruct);
}
private void InitializeBackgroundWorker()
{
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.DoWork += backgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
}
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
}
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// do something when finished
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = (BackgroundWorker) sender;
CopyStruct copyStruct = (CopyStruct) e.Argument;
DirectoryInfo di = new DirectoryInfo(copyStruct.sourceDir);
FileInfo[] filelist = di.GetFiles("*.*");
int numFiles = filelist.Length;
for (int i = 0; i < numFiles; i++)
{
FileInfo file = filelist[i];
File.Copy(Path.Combine(copyStruct.sourceDir, file.Name), Path.Combine(copyStruct.destDir, file.Name), true);
// This line updates the progress bar
worker.ReportProgress((int) ((float) i/numFiles*100));
}
}
This almost doesn't check for errors, so you'll have to add this, but it works with multiple test directories on my system.
a source to share
For the progress bar to update in your UI, the process that is working on something must be running on a different thread (otherwise it will block the UI thread and the UI will not update). BackgroundWorker is a good candidate for this.
Loop the file copy in the DoWork background work event and call the BackgroundWorker.ReportProgress method to report the progress. In the event handler for the ProgressChanged event, you can set a value in your ProgressBar control. You start this process by calling the RunWorkerAsync method on the BackgroundWorker component.
a source to share
Since you are new to programming, start with this.
Add to
Application.DoEvents();
after
progressBar1.PerformStep();
This should make your application work now. Ultimately you will want to move the copy process to a thread / background worker. But without knowing your abilities, Application.DoEvents () is probably the simplest fix, but not the preferred fix.
a source to share