C# 如何使用WebClient异步下载许多图像?
我想要的是开始下载第一个图像并将其保存到硬盘。 下载完成后,progressBar 100%开始下载下一个图像。等等 我试过这个:C# 如何使用WebClient异步下载许多图像?,c#,.net,winforms,C#,.net,Winforms,我想要的是开始下载第一个图像并将其保存到硬盘。 下载完成后,progressBar 100%开始下载下一个图像。等等 我试过这个: 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;
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;
namespace SatelliteImages
{
public partial class Form1 : Form
{
int count = 0;
public Form1()
{
InitializeComponent();
ExtractImages ei = new ExtractImages();
ei.Init();
startDownload();
}
private void startDownload()
{
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
foreach (string url in ExtractImages.imagesUrls)
{
client.DownloadFileAsync(new Uri(url), @"C:\Temp\TestingSatelliteImagesDownload\" + count + ".jpg");
}
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
double bytesIn = double.Parse(e.BytesReceived.ToString());
double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
double percentage = bytesIn / totalBytes * 100;
label1.Text = "Downloaded " + e.BytesReceived + " of " + e.TotalBytesToReceive;
progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString());
}
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
label1.Text = "Completed";
count++;
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
列表imagesUrls包含类似以下格式的链接,例如第一项:
如果我能在chrome上浏览到这个链接,那就好了。
但当我试图下载图像并将其保存在硬盘上时,我遇到了一个异常:
client.DownloadFileAsync(new Uri(url), @"C:\Temp\TestingSatelliteImagesDownload\" + count + ".jpg");
其他信息:WebClient不支持并发I/O操作
System.NotSupportedException was unhandled
HResult=-2146233067
Message=WebClient does not support concurrent I/O operations.
Source=System
StackTrace:
at System.Net.WebClient.ClearWebClientState()
at System.Net.WebClient.DownloadFileAsync(Uri address, String fileName, Object userToken)
at System.Net.WebClient.DownloadFileAsync(Uri address, String fileName)
at SatelliteImages.Form1.startDownload() in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\Form1.cs:line 37
at SatelliteImages.Form1..ctor() in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\Form1.cs:line 27
at SatelliteImages.Program.Main() in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\Program.cs:line 19
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
您只能在webclient实例不忙之前使用它,因为它不支持并发调用。因此,每次下载都必须使用新的
WebClient
实例,或者在每次下载结束后链接调用,如下所示:
//On initialize form :
WebClient client = new WebClient();
//On start download :
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadFileAsync(new Uri(url), @"C:\Temp\TestingSatelliteImagesDownload\" + ExtractImages.imagesUrls[currentImageIndex] + ".jpg");
...
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if(currentImageIndex<ImageToDownloadCount){
currentImageIndex +=1;
client.DownloadFileAsync(new Uri(url), @"C:\Temp\TestingSatelliteImagesDownload\" + ExtractImages.imagesUrls[currentImageIndex] + ".jpg");
}
label1.Text = "Completed";
count++;
}
//初始化表单时:
WebClient客户端=新的WebClient();
//开始下载时:
client.DownloadProgressChanged+=新的DownloadProgressChangedEventHandler(client\u DownloadProgressChanged);
client.DownloadFileCompleted+=新的AsyncCompletedEventHandler(client\u DownloadFileCompleted);
client.DownloadFileAsync(新Uri(url),@“C:\Temp\testingsatellitiemagesdownload\”+ExtractImages.imagesUrls[currentImageIndex]+“.jpg”);
...
无效客户端\u下载文件已完成(对象发送方,AsyncCompletedEventArgs e)
{
如果(currentImageIndex用于异步下载
public event EventHandler TaskCompleted;
public async void DownloadAsync()
{
String[] urls = { "http://media.salon.com/2014/10/shutterstock_154257524-1280x960.jpg",
"http://www.samsung.com/us/2012-smart-blu-ray-player/img/tv-front.png" };
var tasks = urls.Select((url, index) =>
{
var fileName = String.Format(@"c:\temp\image-{0}.jpg", index);
var client = new WebClient();
return client.DownloadFileTaskAsync(url, fileName);
});
await Task.WhenAll(tasks).ContinueWith(x =>
{
if (TaskCompleted != null)
{
TaskCompleted(this, EventArgs.Empty);
}
});
}
请参见此处:-webclient不允许同时进行多个请求。您必须将其包装为异步方法,以同步调用webclient并返回图像。您是否考虑过使用HttpClient
而不是webclient
?