I'm using WebClient's DownloadStringAsync method to download an html page if the user clicks a certain button. If they want to stop the current operation before it's completed and start a new one, I call CancelAsync method and also set the WebClient object to null. In the event handler of the second button, I also reinitialize the WebClient object and finally attempt to download new content. The WebClient object is a global variable. The error I'm getting is:
WebClient does not support concurrent I/O operations.
Is there a way to force the WebClient to cancel its current operation and start a new one?
This seems like you are trying to download the second file before the first download was completed - with the same instance of WebClient. Creating new instance of WebClient should definitely solve that issue. CancelAsync() attempts to cancel the download in progress, but it might be still running for a short while. After the download is completed/canceled, the DownloadStringCompleted event handler will be raised, allowing you to commence new download with the same instance of WebClient.
The error you are seeing sounds more like an attempt at cross-thread usage of the WebClient which is NOT allowed. In other words, the WebClient must be created on the same thread which will eventually call DownloadStringAsync. Make sense?
You'll need to rethink your design a little. You might consider using the ThreadLocalAttribute if you really want to keep instances of WebClient globally accessible.
You can write a single WebClient class and you can call it in a loop with different async request. As,
WebClient client = new WebClient();
try
{
client.DownloadStringCompleted += (object newSender, DownloadStringCompletedEventArgs e) =>
{
Dispatcher.BeginInvoke(() =>
{
try
{
var response = e.Result;
// your response logic.
}
catch (Exception)
{
MessageBox.Show("Problem occured");
}
});
};
}
catch
{
MessageBox.Show("Problem occured");
}
finally
{
if (userHasCanceled)
client.DownloadStringAsync(new Uri("xyz"));
}
client.DownloadStringAsync(new Uri("abc"));
So when you call client.CancelAsyn()
it might throw an exception
, which is handled in try-catch block and at last you can call a new async request in finally block. You can also put check in finally block to confirm whether user has canceled
the operation, if yes
then call new async request else
do nothing.
I hope this is what you were looking for.