dadou dadou - 3 months ago 18
C# Question

BackgroundWorker is canceling only once

I have a problem when using BackgroundWorker Cancellation, it's working only once.

In the second time it goes to the finish event.

Do i need to use: backgroundWorker.Dispose() after canceling it?

Here's my code:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{

//some logic here before calling the copy method

//copy folder method
DirectoryCopy(source, destDirName, true,sender,e);
}

private void DirectoryCopy(string sourceDirName, string destDirName, object sender, DoWorkEventArgs e)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourceDirName);

if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}

DirectoryInfo[] dirs = dir.GetDirectories();
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}

// Get the files in the directory and copy them to the new location.
FileInfo[] files = dir.GetFiles();

foreach (FileInfo file in files)
{
Size += Math.Round(((double)file.Length / 1048576), 2);
string temppath = System.IO.Path.Combine(destDirName, file.Name);
int buflen = 1024;
byte[] buf = new byte[buflen];
using (FileStream sourceStream = new FileStream(file.FullName, FileMode.Open))
{
using (FileStream destStream = new FileStream(temppath, FileMode.CreateNew))
{
while (true)
{
if ((sender as BackgroundWorker).CancellationPending)
{
e.Cancel = true;
return;
}
//Progress Logic code
}
}
}
i++;
}

////If copying subdirectories, copy them and their contents to new location.
if (copySubDirs)
{
// Copy Sub-Directories Logic
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
MessageBox.Show("You cancel the copy!");
}

else
{
MessageBox.Show("All the files were copied!");
}
btnCopy.Visibility = Visibility.Visible;
btnCancel.Visibility = Visibility.Hidden;
}

private void btnCancel_Click(object sender, RoutedEventArgs e)
{
backgroundWorker1.CancelAsync();
}


Thank you for your help.

Answer

Once a BackgroundWorker has completed, it cannot be restarted. Calling Dispose() on it is something you should do, but it will NOT allow you to restart it.

You will need to either create a new BackgroundWorker or use the more modern async style programming (if you're using .Net 4.5 or later).