I made this code example which successfully uses a BackgroundWorker to advance a progress bar in a for loop.
Now I'm trying to adapt it to work with the following recursive file copy method so that it shows me how far along the copying is, but the following code is giving me the error "This BackgroundWorker is currently busy and cannot run multiple tasks concurrently."
What do I need to change so that this recursive method does not get these threading issues?
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<DockPanel LastChildFill="True" HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="10">
<TextBlock DockPanel.Dock="Top" Text="{Binding PageTitle}" Style="{DynamicResource PageTitleStyle}"/>
<TextBlock DockPanel.Dock="Top" Text="{Binding PageDescription}" Style="{DynamicResource PageDescriptionStyle}"/>
<Button x:Name="Button_Start" HorizontalAlignment="Left" DockPanel.Dock="Top" Content="Start Task" Click="Button_Start_Click" Height="25" Width="200"/>
<ProgressBar x:Name="ProgressBar"
HorizontalAlignment="Left"
Margin="0 10 0 0"
Height="23"
Width="500"
Minimum="0"
Maximum="100"
/>
</DockPanel>
</Window>
code-behind:
using System.Windows;
using System.ComponentModel;
using System.Threading;
using System.IO;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
private BackgroundWorker backgroundWorker;
int thread1percentageFinished = 0;
private int totalFilesToCopy;
private int numberOfFilesCopied;
public MainWindow()
{
InitializeComponent();
ProgressBar.Visibility = Visibility.Collapsed;
}
private void Button_Start_Click(object sender, RoutedEventArgs e)
{
int totalFilesToCopy = 1000;
int numberOfFilesCopied = 0;
backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.WorkerSupportsCancellation = true;
ProgressBar.Visibility = Visibility.Visible;
CopyFolder(@"C:\test", @"C:\test2");
}
void CopyFolder(string sourceFolder, string destFolder)
{
backgroundWorker.DoWork += (s, args) =>
{
BackgroundWorker worker = s as BackgroundWorker;
if (!Directory.Exists(destFolder))
Directory.CreateDirectory(destFolder);
string[] files = Directory.GetFiles(sourceFolder);
foreach (string file in files)
{
string name = Path.GetFileName(file);
string dest = Path.Combine(destFolder, name);
File.Copy(file, dest, true);
numberOfFilesCopied++;
float percentageDone = (numberOfFilesCopied / (float)totalFilesToCopy) * 100f;
worker.ReportProgress((int)percentageDone);
}
string[] folders = Directory.GetDirectories(sourceFolder);
foreach (string folder in folders)
{
string name = Path.GetFileName(folder);
string dest = Path.Combine(destFolder, name);
CopyFolder(folder, dest);
}
};
backgroundWorker.ProgressChanged += (s, args) =>
{
thread1percentageFinished = args.ProgressPercentage;
ProgressBar.Value = thread1percentageFinished;
};
backgroundWorker.RunWorkerCompleted += (s, args) =>
{
Button_Start.IsEnabled = true;
ProgressBar.Visibility = Visibility.Collapsed;
ProgressBar.Value = 0;
};
backgroundWorker.RunWorkerAsync();
}
}
}