WebClient не поддерживает одновременные операции ввода-вывода
Как я могу получить эту ошибку с помощью в событии DownloadStringCompleted? Разве это не значит, что закончилось? Есть ли еще одно событие, которое я могу запустить?
Я получаю эту ошибку крайне редко, но время от времени это произойдет на моем телефоне WP7. У меня есть веб-клиент, который я запускаю снова и снова, и я запускаю его снова из завершенного события. Это происходит потому, что все еще открыто какое-то устаревшее соединение? Есть ли способ предотвратить это 100%?
Я проверил, есть ли вероятность, чтобы поток прошел сам по себе, но он запускается только из завершенного события.
Как я могу быть уверен, что когда завершено полное событие, клиент больше не isBusy? Одно из предложений заключалось в том, чтобы добавить какое-то время со спящим потоком, пока клиент занят.
Некоторые псевдокоды.
var client = new WebClient("URL 1");
client.CompletedEvent += CompletedEvent;
client.downloadasync();
void CompletedEvent(){
Dosomestuff;
client.downloadasync(); //This is where we break.
}
Ответы
Ответ 1
Единственный ответ - создать новый веб-клиент в рамках Завершенного события. Вы не можете установить его на новый, так как webclient только для чтения. Создание нового клиента - единственное решение. Это позволяет старому клиенту заполнить фон. Это имеет небольшие последствия для памяти, поскольку вы создаете новый экземпляр вместо повторного использования старого. Но сборщик мусора должен держать его в чистоте, если ваш объем настройки настроен правильно.
Ответ 2
WebClient поддерживает только одну операцию, он не может загружать несколько файлов. Вы не указали свой код, но я предполагаю, что вы каким-то образом уволили новый запрос до того, как старое будет завершено. Моя ставка заключается в том, что WebClient.IsBusy
истинно, когда вы пытаетесь выполнить другую выборку.
Смотрите следующий поток:
wb.DownloadFileAsync throw "WebClient не поддерживает одновременные операции ввода-вывода." Исключение
Ответ 3
Вместо использования 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);
}
}
});
Ответ 4
Решение, я нашел, это использовать несколько объектов WebClient, поэтому для изменения вашего примера псевдокода; попробуйте
var client = new WebClient("URL 1");
client.CompletedEvent += CompletedEvent;
client.downloadasync();
void CompletedEvent(){
Dosomestuff;
var client2 = new WebClient();
client2.downloadasync();
}