c# - 我如何添加一个新的进度条来显示整体下载?

标签 c# .net winforms

代码有效。 但是,现在我在 progressBar1 中显示每个文件的下载进度。 但是我想在设计器中添加(已添加)progressBar2来显示整体下载进度。我如何计算它并将其显示在 progressBar2 中?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Threading;
using System.Diagnostics;

namespace DownloadFiles
{
    public partial class Form1 : Form
    {  
        Stopwatch sw = new Stopwatch();    
        int count = 0;
        PictureBoxBigSize pbbs;
        ExtractImages ei = new ExtractImages();

        public Form1()
        {
            InitializeComponent();

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void btnDownload_Click(object sender, EventArgs e)
        {
            downloadFile(filesUrls);
        }

        private Queue<string> _downloadUrls = new Queue<string>();

        private async void downloadFile(IEnumerable<string> urls)
        {
            foreach (var url in urls)
            {
                _downloadUrls.Enqueue(url);
            }

            await DownloadFile();
        }

        private async Task DownloadFile()
        {
            if (_downloadUrls.Any())
            {
                WebClient client = new WebClient();
                client.DownloadProgressChanged += ProgressChanged;
                client.DownloadFileCompleted += Completed;

                var url = _downloadUrls.Dequeue();

                await client.DownloadFileTaskAsync(new Uri(url), @"C:\Temp\DownloadFiles\" + count + ".jpg");
                return;
            }
        }

        private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            // Calculate download speed and output it to labelSpeed.
            Label2.Text = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));

            // Update the progressbar percentage only when the value is not the same.
            double bytesIn = double.Parse(e.BytesReceived.ToString());
            double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
            double percentage = bytesIn / totalBytes * 100;
            ProgressBar1.Value = int.Parse(Math.Truncate(percentage).ToString());//e.ProgressPercentage;
            // Show the percentage on our label.
            Label4.Text = e.ProgressPercentage.ToString() + "%";

            // Update the label with how much data have been downloaded so far and the total size of the file we are currently downloading
            Label5.Text = string.Format("{0} MB's / {1} MB's",
                (e.BytesReceived / 1024d / 1024d).ToString("0.00"),
                (e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"));
        }

        // The event that will trigger when the WebClient is completed
        private async void Completed(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {
                MessageBox.Show("Download has been canceled.");
            }
            else
            {
                ProgressBar1.Value = 100;
                count++;
                await DownloadFile();   
            }
        }
    }
}

最佳答案

尝试添加此方法来计算需要下载的字节总数(或修改现有方法,无论您决定如何):

long totalBytesToDownload = 0;
List<FileInfo> files;
private void getTotalBytes(IEnumerable<string> urls)
{
    files = new List<FileInfo>(urls.Count());
    foreach(string url in urls)
    {
        files.Add(new FileInfo(url));
    }
    files.ForEach(file => totalBytesToDownload += file.Length);
}

所以我在这里所做的是添加一个方法来获取要下载的字节总数,还创建了一个变量来存储您尝试下载的每个文件的文件大小,它将在此处用于分钟。

首先,在您的 Complete 事件中,我们需要创建一个变量来存储每次文件下载后的字节数,我们稍后会用到它。

long bytesFromCompletedFiles = 0;
private async void Completed(object sender, AsyncCompletedEventArgs e)
{
    if (e.Cancelled == true)
    {
        MessageBox.Show("Download has been canceled.");
    }
    else
    {
        ProgressBar1.Value = 100;
        count++;
        bytesFromCompletedFiles += files[count - 1].Length;
        await DownloadFile();
    }
}

最后,我们可以更新 ProgressChanged 事件来完成您的 ProgressBar2:

private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    // Calculate download speed and output it to labelSpeed.
    Label2.Text = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));

    // Update the progressbar percentage only when the value is not the same.
    double bytesInCurrentDownload = double.Parse(e.BytesReceived.ToString());
    double totalBytesCurrentDownload = double.Parse(e.TotalBytesToReceive.ToString());
    double percentageCurrentDownload = bytesInCurrentDownload / totalBytesCurrentDownload * 100;
    ProgressBar1.Value = int.Parse(Math.Truncate(percentageCurrentDownload).ToString());//e.ProgressPercentage;
                                                                         // Show the percentage on our label.
    Label4.Text = e.ProgressPercentage.ToString() + "%";

    // Update the label with how much data have been downloaded so far and the total size of the file we are currently downloading
    Label5.Text = string.Format("{0} MB's / {1} MB's",
        (e.BytesReceived / 1024d / 1024d).ToString("0.00"),
        (e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"));

    //Let's update ProgressBar2
    double totalBytesDownloaded = e.BytesReceived + bytesFromCompletedFiles;
    double percentageTotalDownload = totalBytesDownloaded / totalBytesToDownload * 100;
    ProgressBar2.Value = int.Parse(Math.Truncate(percentageTotalDownload)).ToString();
}

希望这对您有用!

关于c# - 我如何添加一个新的进度条来显示整体下载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41527768/

相关文章:

c# - Ubuntu 上的目标语言是什么?

c# - Throttle - 最多每 N 毫秒调用一个函数?

c# - 如何使用反射创建值类型的实例

c# - LINQ IEnumerable<string> 中的语法

c# - 在设计器中查看表单时出现错误 - 我该如何避免这种情况?

c# - 将具有多个参数的 F# 函数转换为 Func 类型 - MathNet.Numerics

c# - .NET Core 和 PCL 之间有什么区别?

c# - 在 C# 中通过反射访问数据时的并发问题

c# - 如何在 Timer Tick 事件上使用 TimeSpan 显示秒数

c# - 左右对齐 richtextbox c#