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是List
此代码正常运行但我现在想要添加两个progressBars,第一个将显示整体进度,第二个将显示每个文件下载进度。
我已经在设计师progressBar1和progressBar2
中但不确定如何将它们与async Task和await一起使用。
到目前为止我尝试了什么:
添加了一个DownloadProgressChanged事件处理程序:
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%。
答案 0 :(得分:1)
使用IProgress<T>
界面和Progress<T>
类。
async Task SomeAsynMethod(IProgress<double> progress)
{
double percentCompletedSoFar = 0;
while (!completed)
{
// your code here to do something
if (progress != null)
{
prgoress.Report(percentCompletedSoFar);
}
}
}
以下是如何在调用代码中使用它:
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窗体应用程序,并添加一个名为Label
的{{1}},一个名为label1
的{{1}}和一个名为ProgressBar
的{{1}} {1}}。在实际场景中,您可以为控件提供更有意义的名称。使用此代码替换表单中的所有代码。
这个简单的应用程序的作用是:
当您按下按钮时,它会删除“Progress.txt”文件(如果存在)。然后它会调用progressBar
。此例程创建一个实现Button
接口的button1
实例。它订阅SomeAsyncRoutine
事件。然后它调用Progress<double>
将实例IProgress<double>
传递给它。报告进度后,它会更新ProgressChanged
并更新SomeAsyncMethod(progress)
属性。
progress
模仿了一些工作。使用从1开始并在100结束的循环,它将循环变量(progress)写入文件,休眠100ms然后进行下一次迭代。
名为“Progress.txt”的bin文件夹中文件的进度。显然,在一个真实的应用程序中,你将做一些有意义的工作。
我将应用程序中的方法名称保留为与我提供的代码段相同,因此很容易映射。
progressBar1.Value