C# WebClient 不支持并发 I/O 操作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9765109/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WebClient does not support concurrent I/O operations
提问by firebellys
How can I get this error from with in the DownloadStringCompleted Event? Doesn't that mean, it's finished? Is there another event I can fire this from?
如何从 DownloadStringCompleted 事件中获取此错误?不是说完了吗?我可以从另一个事件中触发它吗?
I get this error extremely rarely, but once in a while it will happen on my WP7 phone. I have a web client that I fire over and over, and I fire it again from the completed event. Is this happening because there is still some stale connection open? Is there a way to prevent this 100%?
我很少收到此错误,但偶尔它会在我的 WP7 手机上发生。我有一个网络客户端,我一遍又一遍地触发,然后从完成的事件中再次触发它。发生这种情况是因为仍有一些陈旧的连接打开吗?有没有办法 100% 防止这种情况发生?
I have checked to see if there is a chance for the thread to walk over itself, but it is only fired from within the completed event.
我已经检查过线程是否有机会遍历自身,但它仅在已完成的事件中被触发。
How can I be sure, when the complete event is fired, the client is no longer isBusy? One suggestion was to add a while with a thread sleep while the client is busy.
我怎么能确定,当完成事件被触发时,客户端不再是忙碌的?一个建议是在客户端忙碌时添加一段时间并让线程休眠。
Some pseudo code.
一些伪代码。
var client = new WebClient("URL 1");
client.CompletedEvent += CompletedEvent;
client.downloadasync();
void CompletedEvent(){
Dosomestuff;
client.downloadasync(); //This is where we break.
}
采纳答案by ColinE
The WebClient only supports a single operations, it cannot download multiple files. You haven't shown your code, but my guess is that you are somehow firing a new request before the old is completed. My bet is that WebClient.IsBusyis true when you attempt to perform another fetch.
WebClient 只支持单次操作,不能下载多个文件。您还没有显示您的代码,但我的猜测是您在旧请求完成之前以某种方式触发了一个新请求。我敢打赌,WebClient.IsBusy当您尝试执行另一个提取时,情况确实如此。
See the following thread:
请参阅以下线程:
wb.DownloadFileAsync throw "WebClient does not support concurrent I/O operations." exception
回答by firebellys
The only answer is to create a new webclient within the scope of the Completed Event. You can't set it to new since webclient is readonly. Creating a new client is the only solution. This allows the old client to complete in the background. This does have slight memory implications since you are creating a new instance instead of reusing an old. But the garbage collector should keep it clean if your scope is setup right.
唯一的答案是在 Completed Event 的范围内创建一个新的 webclient。您不能将其设置为 new,因为 webclient 是只读的。创建新客户端是唯一的解决方案。这允许旧客户端在后台完成。这确实有轻微的内存影响,因为您正在创建一个新实例而不是重用旧实例。但是如果您的范围设置正确,垃圾收集器应该保持清洁。
回答by Fiach Reid
The solution, I found is to use multiple WebClient objects, so to modify your pseudocode example; try
我发现的解决方案是使用多个 WebClient 对象,以便修改您的伪代码示例;尝试
var client = new WebClient("URL 1");
client.CompletedEvent += CompletedEvent;
client.downloadasync();
void CompletedEvent(){
Dosomestuff;
var client2 = new WebClient();
client2.downloadasync();
}
回答by Ahamed Ishak
Instead of using WebClient use HttpClient to do parallel HTTP calls. Below code shows how to download files.
使用 HttpClient 进行并行 HTTP 调用,而不是使用 WebClient。下面的代码显示了如何下载文件。
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);
}
}
});

