WebClient не поддерживает параллельные операции ввода-вывода - PullRequest
19 голосов
/ 19 марта 2012

Как я могу получить эту ошибку с помощью в событии 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.
}

Ответы [ 4 ]

18 голосов
/ 19 марта 2012

WebClient поддерживает только одну операцию, он не может загружать несколько файлов. Вы не показали свой код, но я предполагаю, что вы каким-то образом запускаете новый запрос до того, как старый будет завершен. Держу пари, что WebClient.IsBusy верно, когда вы пытаетесь выполнить другую выборку.

См. Следующую ветку:

wb.DownloadFileAsync throw "WebClient не поддерживает параллельные операции ввода-вывода." исключение

10 голосов
/ 03 апреля 2012

Единственный ответ - создать нового веб-клиента в рамках завершенного события. Вы не можете установить его на новый, так как веб-клиент доступен только для чтения. Создание нового клиента - единственное решение. Это позволяет старому клиенту завершать работу в фоновом режиме. Это имеет небольшие последствия для памяти, так как вы создаете новый экземпляр вместо повторного использования старого. Но сборщик мусора должен содержать его в чистоте, если ваш объем настроен правильно.

5 голосов
/ 25 сентября 2017

Вместо использования 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);
                }

            }
        });
0 голосов
/ 22 сентября 2017

Решение, которое я нашел, состоит в том, чтобы использовать несколько объектов WebClient, чтобы изменить ваш пример псевдокода; попробовать

var client = new WebClient("URL 1");
client.CompletedEvent += CompletedEvent;
client.downloadasync();

void CompletedEvent(){
Dosomestuff;
var client2 = new WebClient();
client2.downloadasync(); 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...