Dois-je attendre ReadAsStringAsync() si j'ai attendu la réponse que je joue ReadAsStringAsync ()?
Dois-je attendent ReadAsStringAsync()
si je attendu la réponse sur laquelle je joue ReadAsStringAsync()
? Pour clarifier davantage, quelle est la différence ou le droit chemin entre la suite? Sont-ils effectivement la même chose?
var response = await httpClient.GetAsync("something");
var content = await response.Content.ReadAsStringAsync();
return new AvailableViewingTimesMapper().Map(content);
OU
var response = await httpClient.GetAsync("something");
var content = response.Content.ReadAsStringAsync();
return new AvailableViewingTimesMapper().Map(content.Result);
Je pense que vous ne faites
Vous ne devriez jamais faire
Votre premier exemple est la bonne selon ci-dessous les réponses, mais sérieusement lu toutes les réponses, comme ils l'expliquent pourquoi l'exemple de deux peut introduire de l'interblocage.
var content = response.Content.ReadAsStringAsync();
si tu voulais faire quelque chose avec la tâche avant d'utiliser le résultat.Vous ne devriez jamais faire
Map(content.Result)
vous pouvez bloquer votre programme, si vous allez reporter, vous devez toujours utiliser les attendent. Map(await content)
,Votre premier exemple est la bonne selon ci-dessous les réponses, mais sérieusement lu toutes les réponses, comme ils l'expliquent pourquoi l'exemple de deux peut introduire de l'interblocage.
OriginalL'auteur Toby Holland | 2015-01-28
Vous devez vous connecter pour publier un commentaire.
Votre premier exemple est la bonne. Le deuxième exemple n'est pas le rendement au cours de l'opération asynchrone. Au lieu de cela, obtenir la valeur de la
content.Result
de la propriété, vous forcez le thread en cours d'attendre jusqu'à ce que l'opération asynchrone est terminée.En outre, comme intervenant Scott Chamberlain points, en bloquant le thread en cours, il est possible d'introduire la possibilité de blocage. Cela dépend du contexte, mais un scénario commun pour
await
est l'utilisation de cette instruction dans le thread de l'INTERFACE utilisateur, et le thread d'INTERFACE utilisateur doit rester réactif pour une variété de besoins, mais y compris pour être en mesure de gérer la réalisation d'un attendu de l'opération.Si vous évitez de le second motif, c'est à dire récupérer la valeur de l'
Result
propriété à partir d'unTask
vous ne savez pas terminée, vous pouvez non seulement assurer l'efficacité de l'utilisation de votre fils, vous pouvez également assurer l'encontre de cette commune de blocage piège.async
il n'y a aucune raison de l'appeler.Result
surawait
sur une tâche.OriginalL'auteur Peter Duniho
La raison pour laquelle
ReadAsString
est unasync
méthode est, qui fait de la lecture des données est une Opération e /s. Le contenu peut tout simplement pas être complètement chargé, même si vous avez déjà le résultat http. Il n'y a pas plus de threads ou de grosses charges de calcul impliqués.HttpClient.GetAsync
vous permet d'ajouter unHttpCompletionOption
avoir leGetAsync
ne reviennent qu'une fois l'ensemble de laHttpResult
a été chargé. Dans ce cas,HttpContent.ReadAsStringAsync
permettra de compléter de façon synchrone (un soi-disant fastpath) parce que le contenu est déjà là.Donc vous devriez certainement l'attendent.
Aussi: Comme il s'agit probablement de la bibliothèque de code qui ne dépend pas de retour à la thread de l'INTERFACE utilisateur, vous devez ajouter
.ConfigureAwait(false)
à tous attendus des appels de méthode.ConfigureAwait(false)
serait exactement la mauvaise chose à faire.mais nous voyons tout le code entre la première
await
et l'instruction de retour, il semble y avoir aucune INTERFACE utilisateur n'appels alors ce serait un bon candidat pourConfigureAwait(false)
probablement, mais sans contexte, il est difficile d'être sûr. Pour tout ce que nous savons, l'OP simplement gommés de l'INTERFACE utilisateur-les choses liées. Mon souci serait, en ajoutant
ConfigureAwait(false)
de code où il ne devrait pas être présent est bien pire que de ne pas avoir dans le code à l'endroit où il devrait être présent. I. e. ce dernier est tout simplement une optimisation (pour le code qui est par ailleurs correcte), alors que l'ancien de casser quelque chose.raconte la tâche qu'il n' pas besoin de courir à la poursuite dans le contexte actuel. C'est très bien pour tout ce ne sont pas liées à l'INTERFACE utilisateur de code; mais si la poursuite contient le code qui exige l'exécution dans le contexte actuel (c'est à dire le thread d'INTERFACE utilisateur), tels que l'accès à certains objets d'INTERFACE utilisateur, appelant
ConfigureAwait(false)
sera la cause de la poursuite à être exécuté sur un thread autre que le thread de l'INTERFACE utilisateur, avec le résultat que lorsque l'objet d'INTERFACE est accessible,InvalidOperationException
(ou similaire...c'est Winforms, je ne me souviens pas de WPF sur le dessus de ma tête) sera lancé.à l'aide de
Invoke()
permettrait de contourner le problème, mais serait également assez bien nier le point de l'ensemble de l'aideawait
dans ce scénario.OriginalL'auteur Kai Brummund
Est ici .NET code source pour ReadAsStringAsync.
Si vous regardez plus en LoadIntoBufferAsync() la méthode, vous allez voir, cela permet de garder la lecture de la mémoire tampon de HttpResponse et conduit à un éventuel appel du réseau. Cela signifie qu'il est une bonne pratique d'utiliser attendent au lieu de Résultat.
OriginalL'auteur Teoman shipahi