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

- Reprise des articles Codes-Sources de 2011 à 2013 par Blog de Jérémy Jeanson le 08-21-2018, 16:08

- Office 365: Modifier les jeux de couleur dans les Thèmes des pages classiques de SharePoint Online par Blog Technique de Romelard Fabrice le 08-08-2018, 17:27

- Office 365: Modifier les jeux de couleur dans les Thèmes des pages modernes de SharePoint Online par Blog Technique de Romelard Fabrice le 07-04-2018, 13:26

- Office 365: Script PowerShell pour fixer le Quota Warning de toutes les collections d’un tenant par Blog Technique de Romelard Fabrice le 07-03-2018, 14:16

- MVP Award 2018-2019 par Blog de Jérémy Jeanson le 07-02-2018, 20:39

- Reprise des articles de 2014 à aujourd’hui par Blog de Jérémy Jeanson le 06-20-2018, 13:00

- Office 365: Comment créer un sous-plan dans Office 365 Planner par Blog Technique de Romelard Fabrice le 06-14-2018, 17:19

- Office 365: Script PowerShell de création de sous-sites basés sur CSOM ou PnP par Blog Technique de Romelard Fabrice le 06-12-2018, 14:58

- Office 365: Comment exporter tous les comptes Azure Active Directory ayant une license via PowerShell par Blog Technique de Romelard Fabrice le 05-17-2018, 13:46

- PowerShell: Comment avoir le Country Name depuis un Country Code par Blog Technique de Romelard Fabrice le 05-17-2018, 13:20