Est async/await adapté pour les méthodes qui sont à la fois des OI et en CPU?
La documentation MSDN apparaît, en l'état async
et await
sont adaptés pour IO-tâches limitées alors que Task.Run
doit être utilisé pour le CPU des tâches.
Je travaille sur une application qui effectue les requêtes HTTP pour récupérer des documents HTML, dont il analyse ensuite. J'ai une méthode qui ressemble à ceci:
public async Task<HtmlDocument> LoadPage(Uri address)
{
using (var httpResponse = await new HttpClient().GetAsync(address)) //IO-bound
using (var responseContent = httpResponse.Content)
using (var contentStream = await responseContent.ReadAsStreamAsync())
return await Task.Run(() => LoadHtmlDocument(contentStream)); //CPU-bound
}
Est-ce une bonne et convient à une utilisation de async
et await
, ou suis-je sur-de les utiliser?
Vous devez vous connecter pour publier un commentaire.
Il y a deux bonnes réponses déjà, mais pour ajouter mon 0.02...
Si vous parlez consommer opérations asynchrones,
async
/await
fonctionne très bien pour les I/O-lié et dépendant du PROCESSEUR.Je pense que la MSDN docs ont une légère inclinaison vers la production de opérations asynchrones, dans ce cas, vous ne voulez utiliser
TaskCompletionSource
(ou similaire) pour I/O-lié etTask.Run
(ou similaire) pour le CPU. Une fois que vous avez créé la premièreTask
wrapper, il est préférable consommé parasync
etawait
.Pour votre exemple, il s'agit vraiment de la façon dont beaucoup de temps
LoadHtmlDocument
à prendre. Si vous supprimez leTask.Run
, vous pourrez l'exécuter dans le même contexte que les appelsLoadPage
(éventuellement sur un thread d'INTERFACE utilisateur). Windows 8 lignes directrices précisent que toute opération ayant plus de 50ms doit être faiteasync
... en gardant à l'esprit que 50ms sur votre ordinateur du développeur peut être plus sur la machine d'un client...Donc, si vous pouvez garantir que
LoadHtmlDocument
durera moins de 50ms, vous pouvez exécuter directement:Cependant, je vous recommande
ConfigureAwait
comme @svick mentionné:Avec
ConfigureAwait
, si la requête HTTP n'est pas effectuée immédiatement (de façon synchrone), puis ce sera (dans ce cas) à causeLoadHtmlDocument
à être exécuté sur un thread du pool sans un appel explicite àTask.Run
.Si vous êtes intéressé par
async
la performance à ce niveau, vous devriez vérifier Stephen Toub du vidéo et Article MSDN sur le sujet. Il a des tonnes d'informations utiles.ConfigureAwait(false)
voudrait dire que la Tâche ne devrait pas reprendre sur le contexte, il a commencé à partir, quand il a fini. Pas ce thread fait le travail de la tâche.LoadPage
reprend, il s'exécute sur un thread du pool, puis exécuteLoadHtmlDocument
(bien que sur ce thread du pool).LoadHtmlDocument
est encore essentiellement de blocage et de ne pas déchargé de toute façon.Il est approprié de
await
toute opération qui est asynchrone (c'est à dire représenté par unTask
).Le point clé est que pour les opérations d'e /s, chaque fois que possible, vous souhaitez utiliser une méthode qui est, à la base, asynchrone, plutôt que d'utiliser
Task.Run
sur un blocage de la méthode synchrone. Si vous êtes bloquer un thread (même un thread du pool) lors de l'exécution d'IO, vous n'êtes pas en tirant parti de la puissance réelle de laawait
modèle.Une fois que vous avez créé un
Task
qui représente votre opération, vous n'avez plus de soins si c'est le CPU ou IO lié. Pour l'appelant, c'est juste des async opération qui doit êtreawait
-ed.Il y a plusieurs choses à prendre en compte:
Task.Run()
est probablement une bonne idée. Si les utilisateurs de votre code peut le faire eux-mêmes, s'ils le veulent.Task.Run()
au lieu de courir le code directement, mais il ne devrait pas être important si l'opération prend du temps. (Aussi, il y a une surcharge en rentrant dans le contexte de synchronisation, ce qui est une raison de plus pourquoi vous devriez l'utiliserConfigureAwait(false)
pour la plupart desawait
s dans votre bibliothèque de code).De pondération qui, je pense, à l'aide de
await Task.Run()
est le bon choix ici. Il dispose d'une surcharge, mais aussi certains avantages, qui peuvent être importantes.