在我的Windows窗体应用程序中,某些目录会根据用户请求进行复制。目前,复制这些目录正在UI线程上运行,我无法看到该过程的任何进展。
目前复制功能触发我的以下代码。
private void button5_Click(object sender, EventArgs e)
{
string[] str = comboBox2.Text.Split(' ');
string username = str[2].Replace("[", "").Replace("]", "");
label3.Text = comboBox3.Text;
DialogResult result = MessageBox.Show("Do you want to copy " + comboBox3.Text + " mozilla profile for " + username + " to Selected Servers?", "Confirmation", MessageBoxButtons.YesNoCancel);
if (result == DialogResult.Yes)
{
if (myCheck.Checked == true)
{
string path = getPath(comboBox3.Text);
try
{
string source = path + "\\Appdata";
string dest = "\\\\192.168.1.40\\C$\\Users\\" + username + "\\AppData\\Local\\Mozilla";
Copy(@source, @dest);
}
}
}
}
复制功能有以下代码。
public void Copy(string sourceDirectory, string targetDirectory)
{
DirectoryInfo diSource = new DirectoryInfo(sourceDirectory);
DirectoryInfo diTarget = new DirectoryInfo(targetDirectory);
//Gets size of all files present in source folder.
GetSize(diSource, diTarget);
maxbytes = maxbytes / 1024;
progressBar1.Maximum = maxbytes;
CopyAll(diSource, diTarget);
}
public void CopyAll(DirectoryInfo source, DirectoryInfo target)
{
if (Directory.Exists(target.FullName) == false)
{
Directory.CreateDirectory(target.FullName);
}
foreach (FileInfo fi in source.GetFiles())
{
fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);
total += (int)fi.Length;
copied += (int)fi.Length;
copied /= 1024;
progressBar1.Visible = true;
progressBar1.Step = copied;
progressBar1.PerformStep();
label14.Visible = true;
label14.Text = (total / 1048576).ToString() + "MB of " + (maxbytes / 1024).ToString() + "MB copied";
label14.Refresh();
}
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
{
DirectoryInfo nextTargetSubDir = target.CreateSubdirectory(diSourceSubDir.Name);
CopyAll(diSourceSubDir, nextTargetSubDir);
}
}
public void GetSize(DirectoryInfo source, DirectoryInfo target)
{
if (Directory.Exists(target.FullName) == false)
{
Directory.CreateDirectory(target.FullName);
}
foreach (FileInfo fi in source.GetFiles())
{
maxbytes += (int)fi.Length;//Size of File
}
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
{
DirectoryInfo nextTargetSubDir = target.CreateSubdirectory(diSourceSubDir.Name);
GetSize(diSourceSubDir, nextTargetSubDir);
}
}
我的代码工作正常,但我无法看到进度,也无法在Label中看到更新。
有人可以帮助我在新帖子中运行此副本,以便我可以看到进度条中的进度。
答案 0 :(得分:0)
不打算为你包装,但我认为以下内容可能会让你走上正轨。
鉴于你有"标准" :) button1
和progressBar1
您可以使用以下方法获得良好的非阻止UI更新Task
和BeginInvoke()
。
private void button1_Click(object sender, EventArgs e)
{
progressBar1.Minimum = 0;
progressBar1.Maximum = 5;
Task.Factory.StartNew(() =>
{
for (int i = 0; i <= 5; i++)
{
int progress = i;
progressBar1.BeginInvoke((Action)(() =>
{
progressBar1.Value = progress;
}));
Thread.Sleep(250);
}
});
}
答案 1 :(得分:0)
这是一个使用后台工作者的简单示例。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Shown += new EventHandler(Form1_Shown);
// To report progress from the background worker we need to set this property
backgroundWorker1.WorkerReportsProgress = true;
// This event will be raised on the worker thread when the worker starts
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
// This event will be raised when we call ReportProgress
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
}
void Form1_Shown(object sender, EventArgs e)
{
// Start the background worker
backgroundWorker1.RunWorkerAsync();
}
// On worker thread so do our thing!
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Your background task goes here
for (int i = 0; i <= 100; i++)
{
// Report progress to 'UI' thread
backgroundWorker1.ReportProgress(i);
// Simulate long task
System.Threading.Thread.Sleep(100);
}
}
// Back on the 'UI' thread so we can update the progress bar
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// The progress percentage is a property of e
progressBar1.Value = e.ProgressPercentage;
}
}
您可以在Do_Work和报告进度中执行CopyAll,以在进度条中显示UI的进度。
答案 2 :(得分:0)
试试这个伪代码:
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.WorkerReportsProgress = true;
bw.DoWork +=
new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged +=
new ProgressChangedEventHandler(bw_ProgressChanged);
bw.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
private void button5_Click(object sender, EventArgs e)
{
// rest of the code above this...
if (bw.IsBusy != true)
{
bw.RunWorkerAsync();
}
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
// rest of the code above this...
Copy(@source, @dest);
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Visible = true;
progressBar1.Step = copied;
progressBar1.PerformStep();
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Completed");
}