复制目录的背景工作者

时间:2014-11-19 12:45:05

标签: c# multithreading copy progress-bar backgroundworker

在我的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中看到更新。

有人可以帮助我在新帖子中运行此副本,以便我可以看到进度条中的进度。

3 个答案:

答案 0 :(得分:0)

不打算为你包装,但我认为以下内容可能会让你走上正轨。 鉴于你有"标准" :) button1progressBar1您可以使用以下方法获得良好的非阻止UI更新TaskBeginInvoke()

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");
}