Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Abonnements

async et await : l’asynchrone avec C#5 ça surmégapoutre !

Il y a plein de bonnes raisons de faire de l’asynchrone. Parfois c’est même obligatoire (dans SL pour appeler des services par exemple).

Cependant, la gestion de l’asynchronisme en C# implique souvent une perte de lisibilité et de maintenabilité du code.

Prenons un exemple très simple :

On veut afficher un texte via une Uri :

public void AsyncIntroSingleBefore()
{
    var client = new WebClient();

    client.DownloadStringCompleted += AsyncIntroSingleBefore_DownloadStringCompleted;
    client.DownloadStringAsync(new Uri("http://www.weather.gov"));
}

private void AsyncIntroSingleBefore_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    Foo(e.Result);
}

Avec C#5, on a la possibilité de remplacer ce code par :

public async void AsyncIntroSingle()
{
    Foo(await new WebClient().DownloadStringTaskAsync(new Uri("http://www.weather.gov")));
}

L’intérêt est encore plus flagrant avec l’enchainement séquentiel des appels :

public void AsyncIntroSerialBefore()
{
    var client = new WebClient();

    client.DownloadStringCompleted += AsyncIntroSerialBefore_DownloadStringCompleted_1;
    client.DownloadStringAsync(new Uri("http://www.weather.gov"));
}

void AsyncIntroSerialBefore_DownloadStringCompleted_1(object sender, DownloadStringCompletedEventArgs e)
{
    Foo(e.Result);

    var client = new WebClient();

    client.DownloadStringCompleted += AsyncIntroSerialBefore_DownloadStringCompleted_2;
    client.DownloadStringAsync(new Uri("http://www.weather.gov/climate/"));
}

void AsyncIntroSerialBefore_DownloadStringCompleted_2(object sender, DownloadStringCompletedEventArgs e)
{
    Foo(e.Result);

    var client = new WebClient();

    client.DownloadStringCompleted += AsyncIntroSerialBefore_DownloadStringCompleted_3;
    client.DownloadStringAsync(new Uri("http://www.weather.gov/rss/"));
}

void AsyncIntroSerialBefore_DownloadStringCompleted_3(object sender, DownloadStringCompletedEventArgs e)
{
    Foo(e.Result);
}

qui devient tout simplement :

public async void AsyncIntroSerial()
{
    var client = new WebClient();

    Foo(await client.DownloadStringTaskAsync(new Uri("http://www.weather.gov")));
    Foo(await client.DownloadStringTaskAsync(new Uri("http://www.weather.gov/climate/")));
    Foo(await client.DownloadStringTaskAsync(new Uri("http://www.weather.gov/rss/")));
}

Perso je trouve que ça surmégapoutre !!!

Autre nouveauté : l’introduction de la notion de Task pour Silverlight.

Plus d’infos sur http://blogs.msdn.com/b/ericlippert/archive/2010/10/28/asynchrony-in-c-5-part-one.aspx, sur la video de Toub ToubTaskAsyncDeepDive_ch9.wmv (619 MB) et celle d’Anders http://channel9.msdn.com/Blogs/Charles/Anders-Hejlsberg-Introducing-Async.

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Publié jeudi 28 octobre 2010 22:02 par Matthieu MEZIL

Commentaires

# re: async et await : l’asynchrone avec C#5 ça surmégapoutre ! @ jeudi 28 octobre 2010 23:30

Clair que les mots clefs async/await sont classes ! :)

Troborg

# re: async et await : l’asynchrone avec C#5 ça surmégapoutre ! @ vendredi 29 octobre 2010 09:45

J'ai vu ça, c'est vraiment excellent car actuellement, c'est un peu la galère pour enchaîner les appels asynchrones en effet.

C'est d'autant plus génial que l'interface utilisateur ne sera pas bloqué pendant l'appel et que la gestion d'exception fonctionne !

Aaah, vite, je veux cette fonctionnalité ! ;-)

kakone

# re: async et await : l’asynchrone avec C#5 ça surmégapoutre ! @ vendredi 29 octobre 2010 09:58

Oui ça semble génial. Mais j'ai bien peur que ce soit mal utilisé. Déjà aujourd'hui il y a un nombre incoyable de développeurs qui croient faire de l'asynchrone sans en faire...

J'ai peur que l'on voit ensuite le contraire : des developpeurs qui ne savent pas ce qu'est l'asynchrone et qui vont en faire sans comprendre les contraintes que cela impose :(

en résumé : C'est cool mais j'ai peur des dérives...

JeremyJeanson

# re: async et await : l’asynchrone avec C#5 ça surmégapoutre ! @ vendredi 29 octobre 2010 10:11

Ca SurMegaPoutre...

Halte à la surenchère ! :p

Gribouillon

# re: async et await : l’asynchrone avec C#5 ça surmégapoutre ! @ vendredi 29 octobre 2010 11:14

C'est overpoutrant !

NeuroCypher

# re: async et await : l’asynchrone avec C#5 ça surmégapoutre ! @ vendredi 29 octobre 2010 12:18

+1

Audrey

# re: async et await : l’asynchrone avec C#5 ça surmégapoutre ! @ vendredi 29 octobre 2010 14:15

Ouais effectivement c'est sympa!

fabrice.michellonet

# re: async et await : l’asynchrone avec C#5 ça surmégapoutre ! @ vendredi 29 octobre 2010 20:57

@ Stéphane : "actuellement, c'est un peu la galère pour enchaîner les appels asynchrones" tu devrais regarder RX

Matthieu MEZIL

# re: async et await : l’asynchrone avec C#5 ça surmégapoutre ! @ samedi 6 novembre 2010 13:47

Salut,

Je remarque à l'instant un petit détail qui m'interpelle.

Les DownloadStringAsync originaux deviennent DownloadStringTaskAsync (noter le "Task" entre "String et "Async").

Est-ce un changement dans l'API ou une méthode spécialisée pour l'utilisation avec async et await ?

DjoDjo

# re: async et await : l’asynchrone avec C#5 ça surmégapoutre ! @ jeudi 14 février 2013 15:28

Bonjour,

je migre mes appels asynchrones vers des async await...

Trés bien cela fonctionne mais quand on utilise l'event completed on peut tester si il y a eu des erreurs ou non (if(e.error){})

Hors avec les async await on ne l'a pas et le program plante pour une erreur Uri par exemple.

Comment faire pour intercepter la reponse sous forme de DownloadStringCompletedEventArgs ?

D'avance Merci

François

# re: async et await : l’asynchrone avec C#5 ça surmégapoutre ! @ jeudi 14 février 2013 15:54

@François : en utilisant un try catch autour le l'appel.

try

{

  var value = await client.DownloadStringTaskAsync(new Uri("http://www.weather.gov"));

}

catch(Exception e)

{

  // ...

}

Matthieu MEZIL

# re: async et await : l’asynchrone avec C#5 ça surmégapoutre ! @ jeudi 14 février 2013 18:08

Merci pour ta réponse rapide.

Le try catch c bien mais un peu lourd.

Bon au moins le code est regroupé dans une seule méthode.C'est plus facile a reprendre.

Merci encore

François

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Office 365: Script PowerShell pour assigner des droits Full Control à un groupe défini par Blog Technique de Romelard Fabrice le 04-30-2017, 09:22

- SharePoint 20XX: Script PowerShell pour exporter en CSV toutes les listes d’une ferme pour auditer le contenu avant migration par Blog Technique de Romelard Fabrice le 03-28-2017, 17:53

- Les pièges de l’installation de Visual Studio 2017 par Blog de Jérémy Jeanson le 03-24-2017, 13:05

- UWP or not UWP sur Visual Studio 2015 ? par Blog de Jérémy Jeanson le 03-08-2017, 19:12

- Désinstallation de .net Core RC1 Update 1 ou SDK de Core 1 Preview 2 par Blog de Jérémy Jeanson le 03-07-2017, 19:29

- Office 365: Ajouter un utilisateur ou groupe dans la liste des Site collection Administrator d’un site SharePoint Online via PowerShell et CSOM par Blog Technique de Romelard Fabrice le 02-24-2017, 18:52

- Office 365: Comment créer une document library qui utilise les ContentTypeHub avec PowerShell et CSOM par Blog Technique de Romelard Fabrice le 02-22-2017, 17:06

- [TFS] Supprimer en masse les dépendances à SQL Enterprise ou Developer avant de procéder à une migration par Blog de Jérémy Jeanson le 02-20-2017, 20:30

- Office 365: Attention au volume utilisé par les fichiers de Thèmes de SharePoint Online par Blog Technique de Romelard Fabrice le 02-07-2017, 18:19

- [SCVMM] Supprimer une machine bloquée par Blog de Jérémy Jeanson le 01-31-2017, 21:22