我做了this code example,它成功地使用了BackgroundWorker來在for循環中推進進度條。如何從遞歸方法推進進度條,同時避免線程問題?
現在我正在嘗試將它與以下遞歸文件複製方法一起使用,以便它可以顯示覆制到底有多遠,但以下代碼給了我錯誤「此BackgroundWorker當前正忙碌,不能同時運行多個任務。「
我需要改變什麼,以便這種遞歸方法不會得到這些線程問題?
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>
後臺代碼:
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();
}
}
}