WebClient不支持并发I/O操作
本文关键字:操作 不支持 并发 WebClient | 更新日期: 2023-09-27 18:28:09
如何在DownloadStringCompleted事件中从中获取此错误?这不意味着,它结束了吗?还有其他事件可以触发吗?
我很少遇到这种错误,但偶尔会在我的WP7手机上发生。我有一个web客户端,我一遍又一遍地启动它,并从完成的事件中再次启动它。发生这种情况是因为仍然有一些陈旧的连接打开吗?有没有办法100%防止这种情况发生?
我已经检查了线程是否有机会遍历自己,但它只是从已完成的事件中启动的。
我如何确定,当整个事件被激发时,客户端不再繁忙?一个建议是在客户端繁忙时添加一个线程睡眠时间。
一些伪代码。
var client = new WebClient("URL 1");
client.CompletedEvent += CompletedEvent;
client.downloadasync();
void CompletedEvent(){
Dosomestuff;
client.downloadasync(); //This is where we break.
}
WebClient只支持单个操作,不能下载多个文件。您还没有显示您的代码,但我猜测您在旧请求完成之前以某种方式启动了一个新请求。我敢打赌,当您尝试执行另一次提取时,WebClient.IsBusy
为真。
请参阅以下线程:
wb.DownloadFileAsync抛出";WebClient不支持并发I/O操作"异常
唯一的答案是在Completed Event的范围内创建一个新的web客户端。您不能将其设置为new,因为web客户端是只读的。创建一个新客户端是唯一的解决方案。这允许旧客户端在后台完成。这确实有轻微的内存影响,因为您正在创建一个新实例,而不是重用一个旧实例。但是,如果您的作用域设置正确,垃圾收集器应该保持干净。
不要使用WebClient,而是使用HttpClient进行并行HTTP调用。下面的代码显示了如何下载文件。
HttpClient httpClient = new HttpClient();
var documentList=_documentManager.GetAllDocuments();
documentList.AsParallel().ForAll(doc =>
{
var responseResult= httpClient.GetAsync(doc.FileURLPath);
using (var memStream = responseResult.Result.Content.ReadAsStreamAsync().Result)
{
using (var fileStream =File.Create($"{filePath}''{doc.FileName}"))
{
memStream.CopyTo(fileStream);
}
}
});
我发现的解决方案是使用多个WebClient对象,以便修改您的伪代码示例;尝试
var client = new WebClient("URL 1");
client.CompletedEvent += CompletedEvent;
client.downloadasync();
void CompletedEvent(){
Dosomestuff;
var client2 = new WebClient();
client2.downloadasync();
}
为每个新请求创建一个新的Web客户端。不要重复使用现有的Web客户端实例。
这允许在开始新的请求之前完成第一个请求。这是创建新请求的标准方式。
private async Void SyncParcelStatus(List<string> Urls)
{
try
{
foreach (var URL in WebhookUrls)
{
Task.Factory.StartNew(() => AsyncDownLoad(URL));
}
}
catch (Exception ex)
{
//log Exception
}
}
private async void AsyncDownLoad(string URL)
{
using (WebClient myWebClient = new WebClient())
{
try
{
Uri StringToUri = new Uri(URL);
myWebClient.DownloadStringAsync(StringToUri);
}
catch (Exception ex)
{
//log Exception
}
}
}