使用Progressbar显示后台工作线程中的下载进度

时间:2014-06-30 02:00:25

标签: c# multithreading progress-bar backgroundworker webclient

我编写了一个一次下载文件的应用程序,到目前为止一切正常,但是一旦我尝试让我的进度条显示下载进度,我遇到了一些问题。我以前做过,但这是我第一次在后台工作线程上完成所有这些工作。我之所以使用DownloadFile而不是DownloadFileAsync,是因为我需要一次下载一个文件,我发现这样做有点容易。

这是代码的一部分:

    private void button1_Click(object sender, EventArgs e)
    {
        BackgroundWorker bw = new BackgroundWorker();

        bw.DoWork += bw_DoWork;
        bw.ProgressChanged += bw_ProgressChanged;
        bw.RunWorkerCompleted += bw_RunWorkerCompleted;
        bw.WorkerReportsProgress = true;

        if (!bw.IsBusy)
        {
            bw.RunWorkerAsync();
        }


    }

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show("Patching Completed.");
    }

    void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        barPatch.Value = e.ProgressPercentage;
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        doPatch();

    }

    private void doPatch()
    {

        for (int C = int.Parse(File.ReadAllText("Client.txt")); C < S; C++)
        {
            this.lblC.InvokeEx(lbl => lblC.Text = Convert.ToString(C + 1));
            wc.DownloadFile(String.Format("http://localhost:1234/Launcher/Patches/{0}.zip", C + 1), String.Format("{0}.zip", C + 1));
            File.WriteAllText("Client.txt", Convert.ToString(C + 1));
        }
    }

    void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {


    }

任何帮助表示赞赏! 感谢

2 个答案:

答案 0 :(得分:0)

您可以使用wc.DownloadFileAsync代替wc.DownloadFile

并在wc_DownloadProgressChanged中使用

bw.ReportProgress(e.BytesReceived / e.TotalBytesToReceive * 100);

您可以访问

WebClient.DownloadProgressChanged Event

BackgroundWorker.ReportProgress Method (Int32)

获取更多帮助。

答案 1 :(得分:0)

一个非常脏的技巧,但如果你这样做,你可以获得任何文件大小的进展:

        class InfoForDownload
        {
              public string FileName {get; set;}
              public int FileSize {get; set;}
        }

        int fileSizeFromCheck;

        InfoForDownload info = new InfoForDownload() { FileName = "C:\Users\TheUser\OneDrive\Documents\etc\etc\backup.sql", FileSize = THEFILESIZEOFTHEFILEONEXTERNAL };

        BackgroundWorker checkDownload = new BackgroundWorker();
        checkDownload.WorkerReportsProgress = true;
        checkDownload.ProgressChanged += checkDownload_ProgressChanged;
        checkDownload.DoWork += checkDownload_DoWork;
        checkDownload.RunWorkerAsync(info);

        void downloadWorker_DoWork(object sender, DoWorkEventArgs e)
        {
              BackgroundWorker checkDownload = (sender as BackgroundWorker);
              if (e.Argument != null)
              {
                    InfoForDownload info = (sender as InfoForDownload);
                    ProcessStartInfo cmdStartInfo = new ProcessStartInfo();
                    cmdStartInfo.FileName = @"C:\Windows\System32\cmd.exe";
                    cmdStartInfo.RedirectStandardOutput = true;
                    cmdStartInfo.RedirectStandardError = true;
                    cmdStartInfo.RedirectStandardInput = true;
                    cmdStartInfo.UseShellExecute = false;
                    cmdStartInfo.CreateNoWindow = true;

                    while(info.FileSize > fileSizeFromCheck){
                          Process cmdProcess = new Process();
                          cmdProcess.StartInfo = cmdStartInfo;
                          cmdProcess.ErrorDataReceived += cmd_Error;
                          cmdProcess.OutputDataReceived += cmd_DataReceived;
                          cmdProcess.EnableRaisingEvents = true;
                          cmdProcess.Start();
                          cmdProcess.BeginOutputReadLine();
                          cmdProcess.BeginErrorReadLine();
                          cmdProcess.StandardInput.WriteLine("for %I in (info.FileName) do @echo %~zI");
                          cmdProcess.StandardInput.WriteLine("exit");
                          cmdProcess.WaitForExit();
                          Thread.Sleep(200);
                          Console.WriteLine("The size of the file is " + fileSizeFromCheck + " " + (info.FileSize / fileSizeFromCheck  * 100) + "%");
                          checkDownload.ReportProgress(info.FileSize / fileSizeFromCheck  * 100);
                    }

              }
        }

        void checkDownload_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
              progressBar.Value = e.ProgressPercentage;
        }

        static void cmd_DataReceived(object sender, DataReceivedEventArgs e)
        {
              Console.WriteLine("Output from other process");
              Console.WriteLine(e.Data);
              Int32.TryParse((e.Data / 1024) / 1024, out fileSizeFromCheck);
        }

进行编辑以适合您的使用和名为progressBar的进度条。瞧。脏得很脏。