如何使用两个progressBar控件显示每个文件的下载进度以及所有文件下载的整体进度? [英] How can i use two progressBar controls to display each file download progress and also overall progress of all the files download?

查看:144
本文介绍了如何使用两个progressBar控件显示每个文件的下载进度以及所有文件下载的整体进度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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;

namespace SatelliteImages
{
    public partial class Form1 : Form
    {
        int count = 0;

        public Form1()
        {
            InitializeComponent();

            ExtractImages ei = new ExtractImages();
            ei.Init();
        }

        private async Task DownloadFile(string url)
        {
            using (var client = new WebClient())
            {
                int nextIndex = Interlocked.Increment(ref count);

                await client.DownloadFileTaskAsync(url, @"C:\Temp\TestingSatelliteImagesDownload\" + nextIndex + ".jpg");
            }
        }

        private async Task DownloadFiles(IEnumerable<string> urlList)
        {
            foreach (var url in urlList)
            {
                await DownloadFile(url);
            }
        }

        private async void Form1_Load(object sender, EventArgs e)
        {
            await DownloadFiles(ExtractImages.imagesUrls);
        }
    }
}

imagesUrls是列表

imagesUrls is List

此代码有效,但我现在要添加两个progressBars,第一个将显示总体进度,第二个将显示每个文件下载进度.

This code is working but i want now to add two progressBars the first one will show the overall progress the second one will show each file download progress.

我已经在设计器中的progressBar1和progressBar2

I have already in the designer progressBar1 and progressBar2

但不确定如何在异步任务和等待中使用它们.

But not sure how to use them with the async Task and the await.

到目前为止我尝试过的事情:

What i tried so far:

添加了DownloadProgressChanged事件处理程序:

Added a DownloadProgressChanged event handler:

private async Task DownloadFile(string url)
        {
            using (var client = new WebClient())
            {
                int nextIndex = Interlocked.Increment(ref count);
                client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback);
                await client.DownloadFileTaskAsync(url, @"C:\Temp\TestingSatelliteImagesDownload\" + nextIndex + ".jpg");

            }
        }

我添加了一行:

client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback);

然后在事件中

private void DownloadProgressCallback(object sender, DownloadProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }

但是每次下载文件都不会达到100%.每次下载progressBar时,它会达到另一个百分比,但从未达到100%.

But it's never get to 100% per file download. Each time it's downloading the progressBar is getting to another percentages but never to 100%.

推荐答案

使用 IProgress< T> 界面和以下是在调用代码中使用它的方法:

Here is how to use it in the calling code:

async Task SomeAsyncRoutine()
{
    var progress = new Progress<double>();
    progress.ProgressChanged += (sender, args) => 
    {
        // Update your progress bar and do whatever else you need
    };

    await SomeAsynMethod(progress);
}

示例

要运行以下示例,请创建一个Windows窗体应用程序,并添加一个名为 label1 Label ,一个名为 progressBar 和一个名为 button1 Button .在实际情况下,您将为控件赋予更多有意义的名称.用此代码替换表单中的所有代码.

To run the following example, create a windows form application and add one Label named label1, one ProgressBar named progressBar and one Button named button1. In a real scenario, you would give your controls more meaningful names. Replace all of the code in your form with this code.

此简单应用程序的作用是:

What this simple application does is:

按下按钮时,它将删除"Progress.txt"文件(如果存在).然后,它调用 SomeAsyncRoutine .该例程创建实现 IProgress< double> 接口的 Progress< double> 的实例.它订阅 ProgressChanged 事件.然后,它调用 SomeAsyncMethod(progress)并将实例 progress 传递给它.报告进度后,它将更新 progressBar1.Value ,并更新 label1.Text 属性.

When you press the button, it deletes "Progress.txt" file if it exists. It then calls SomeAsyncRoutine. This routine creates an instance of Progress<double> which implements IProgress<double> interface. It subscribes to the ProgressChanged event. It then calls SomeAsyncMethod(progress) passing the instance progress to it. When the progress is reported, it updates the progressBar1.Value and it updates the label1.Text property.

SomeAsyncMethod 模仿一些工作.使用从1开始到100结束的循环,它将循环变量(progress)写入文件,休眠100ms,然后进行下一次迭代.

The SomeAsyncMethod mimics some work. Using a loop starting at 1 and finishing at 100, it writes the loop variable (progress) to a file, sleeps for 100ms and then does the next iteration.

到bin文件夹中名为"Progress.txt"的文件的进度.显然,在一个实际的应用程序中,您将做一些有意义的工作.

The progress to a file in the bin folder named "Progress.txt". Obviously in a real application you will do some meaningful work.

我将应用程序中的方法名称与我提供的代码段中的名称保持一致,以便轻松进行映射.

I kept the method names in the application the same as in the snippet I provided so it is easily mapped.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private async void button1_Click(object sender, EventArgs e)
    {
        File.Delete("Progress.txt");
        await SomeAsyncRoutine();
    }

    async Task SomeAsynMethod(IProgress<double> progress)
    {
        double percentCompletedSoFar = 0;
        bool completed = false;
        while (!completed)
        {
            // your code here to do something
            for (int i = 1; i <= 100; i++)
            {
                percentCompletedSoFar = i;
                var t = new Task(() => WriteToProgressFile(i));
                t.Start();
                await t;
                if (progress != null)
                {
                    progress.Report(percentCompletedSoFar);
                }
                completed = i == 100;
            }
        }
    }

    private void WriteToProgressFile(int i)
    {
        File.AppendAllLines("Progress.txt",
                    new[] { string.Format("Completed: {0}%", i.ToString()) });
        Thread.Sleep(100);
    }

    async Task SomeAsyncRoutine()
    {
        var progress = new Progress<double>();
        progress.ProgressChanged += (sender, args) =>
        {
            // Update your progress bar and do whatever else you need
            this.progressBar1.Value = (int) args;
            this.label1.Text = args.ToString();
            if (args == 100)
            {
                MessageBox.Show("Done");
            }
        };

        await SomeAsynMethod(progress);
    }
}

这篇关于如何使用两个progressBar控件显示每个文件的下载进度以及所有文件下载的整体进度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆