web-dev-qa-db-fra.com

WebClient ne prend pas en charge les opérations d'E/S simultanées

Comment puis-je obtenir cette erreur avec dans l'événement DownloadStringCompleted? Cela ne veut-il pas dire que c'est fini? Y a-t-il un autre événement pour lequel je peux tirer?

Je reçois très rarement cette erreur, mais cela arrive parfois sur mon téléphone WP7. J'ai un client Web que je déclenche encore et encore, et je le relance à partir de l'événement terminé. Est-ce que cela se produit parce qu'il y a encore une connexion périmée ouverte? Y a-t-il un moyen d'empêcher ce 100%?

J'ai vérifié s'il y avait une chance que le fil se déroule sur lui-même, mais il est uniquement déclenché à partir de l'événement terminé.

Comment puis-je être sûr que, lorsque l'événement complet est déclenché, le client n'est plus isBusy? Une suggestion a été d'ajouter un peu de temps avec un thread sommeil pendant que le client est occupé.

Un pseudo code.

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

void CompletedEvent(){
Dosomestuff;
client.downloadasync(); //This is where we break.
}
19
firebellys

La seule solution est de créer un nouveau client Web dans le cadre de l'événement terminé. Vous ne pouvez pas le définir sur new car webclient est en lecture seule. La création d'un nouveau client est la seule solution. Cela permet à l'ancien client de se terminer en arrière-plan. Cela a de légères implications en termes de mémoire puisque vous créez une nouvelle instance au lieu de réutiliser une ancienne. Mais le ramasse-miettes doit le garder propre si votre étendue est correctement configurée.

10
firebellys

WebClient ne prend en charge qu'une seule opération, il ne peut pas télécharger plusieurs fichiers. Vous n'avez pas montré votre code, mais je suppose que vous lancez une nouvelle demande avant la fin de la précédente. Mon pari est que WebClient.IsBusy est vrai lorsque vous essayez d'effectuer une autre récupération.

Voir le fil suivant:

wb.DownloadFileAsync throw "WebClient ne prend pas en charge les opérations d'E/S simultanées." exception

17
ColinE

Au lieu d'utiliser WebClient, utilisez HttpClient pour effectuer des appels HTTP parallèles. Le code ci-dessous montre comment télécharger des fichiers.

        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);
                }

            }
        });
3
Ahamed Ishak

La solution que j'ai trouvée consiste à utiliser plusieurs objets WebClient afin de modifier votre exemple de pseudocode. essayer

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

void CompletedEvent(){
Dosomestuff;
var client2 = new WebClient();
client2.downloadasync(); 
}
0
Fiach Reid