WebClient does not support concurrent I/O operations
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.IsBusy
is true when you attempt to perform another fetch.
See the following thread:
wb.DownloadFileAsync throw "WebClient does not support concurrent I/O operations." exception
WebClient does not support concurrent I/O operations - DownloadStringAsync - Scraping
Problem is that each time particular WebClient is taken from queue, you register new event handler for worker.DownloadStringCompleted
event without deregistering previous event handler - so event handlers accrues. As a consequence, HandleJson
is called multiple times after async download completes and thus ClientQueue.Add(worker)
returns the same client to the queue multiple times too. It is then just a matter of time before two concurrent downloads are issued on the same WebClient.
This can be easily fixed by registering event handler just once during WebClient creation, and removing item
parameter from HandleJson
method.
BlockingCollection<WebClient> ClientQueue = new BlockingCollection<WebClient>();
for (int i = 0; i < 2; i++)
{
var worker = new WebClient();
worker.DownloadStringCompleted += (sender, e) => HandleJson(sender, e, ClientQueue);
ClientQueue.Add(worker);
}
If parameter item
is required, pass it as a parameter to DownloadStringAsync(uri, item)
and read it from res.UserState
:
foreach (var item in source)
{
var worker = ClientQueue.Take();
worker.DownloadStringAsync(uri, item);
}
public static void HandleJson(object sender, DownloadStringCompletedEventArgs e, BlockingCollection<WebClient> ClientQueue)
{
string item = (string)res.UserState;
...
}
WebClient does not support concurrent I/O error
You need to use a new WebClient instance for each download; it can only do one at a time and you're trying to do a bunch rapidly with your for loop. Initialize a new one in each iteration:
for (int i=0;i<matches.Count;i++)
{
matches.CopyTo(odkazy, 0);
string ano = odkazy[i].ToString();
neco.Add(ano);
WebClient klient = new WebClient();
klient.DownloadFileAsync(new Uri(neco[i]), @"c:\picture{0}.png",i);
Debug.WriteLine(neco[i]);
}
Alternatively you can "chain" the downloads and start the next one in the DownloadFileCompleted event of the single web client.
WebClient does not support concurrent I/O operations
Try defining a single lambda that will encapsulate a single async download and then call that in a loop.
Here's the lambda:
Action<int> downloadFileAsync = i =>
{
var bd = AppDomain.CurrentDomain.BaseDirectory;
var fn = bd + "/" + i + ".7z";
var wc = new WebClient();
DownloadProgressChangedEventHandler dpc = (s, e) =>
{
progressBar1.Value = e.ProgressPercentage;
};
AsyncCompletedEventHandler dfc = null;
dfc = (s, e) =>
{
wc.DownloadProgressChanged -= dpc;
wc.DownloadFileCompleted -= dfc;
CompressionEngine.Current.Decoder.DecodeIntoDirectory(fn, bd);
File.Delete(fn);
wc.Dispose();
};
wc.DownloadProgressChanged += dpc;
wc.DownloadFileCompleted += dfc;
wc.DownloadFileAsync(new Uri(Dlpath + i + "/" + i + ".7z"), fn);
};
You'll note that it nicely detaches all events and also correctly disposes of the WebClient
instance.
Now call it like this:
while (i <= ServID)
{
downloadFileAsync(i);
i++;
}
You'll have to fiddle with the progress bar update to properly show the progress of all the files downloading, but in principle this should work for you.
wb.DownloadFileAsync throw WebClient does not support concurrent I/O operations. exception
When calling DownloadFileAsync method you have to make sure it completes before trying to download again.
This answer will help you.
When using WebClient to download files i'm getting exception does not support concurrent I/O operations how can i solve it?
call the wait Methode of
client.DownloadFileAsync(new Uri(url), downloadDirectory + "\\" + fname + ".gif", url).Wait();
Have a try
Related Topics
Nhibernate How to Query Against an Ilist<String> Property
Azure Key Vault: Access Denied
Get Access to Parent Control from User Control - C#
C# Controlling a Transaction Across Multiple Databases
Is Using an an 'Async' Lambda with 'Task.Run()' Redundant
The Operation Cannot Be Completed Because the Dbcontext Has Been Disposed Using MVC 4
Multiple Identities in ASP.NET Core 2.0
Applying % Number Format to a Cell Value Using Openxml
How to Add Property-Level Attribute to the Typedescriptor at Runtime
Why Generic Ilist<> Does Not Inherit Non-Generic Ilist
Imap Auth in Office 365 Using Oauth2
Does .Net Have a Built-In Eventargs<T>
How to Generate and Auto Increment Id with Entity Framework