Comprendre les Tasks et la programmation asynchrone

ProgrammingInCSharpHeader

publicitemcppreparation

 

Comprendre les Tasks

J’ai toujours été fasciné par le cerveau. Il régule les autres systèmes d’organes du corps, en agissant sur les muscles ou les glandes, et constitue le siège des fonctions cognitives. L’une des performances de cet organe est qu’il peut effectuer plusieurs tâches en parallèle. Je peux par exemple réfléchir, écouter de la musique et marcher en même temps.

Je suis d’accord avec vous, il n’y a rien d’exceptionnel dans tout ça !… C’est notre quotidien :).

En revanche, imaginez un instant que votre cerveau ne puisse réaliser qu’une seule tâche à la fois?…Par exemple, tant que vous réfléchissez vous ne pouvez pas marcher ! :)…Il y en aurait des personnes immobiles dans les rues, n’est-ce pas? 🙂

En C#, réfléchir, écouter de la musique et marcher représentent plusieurs opérations. Chaque opération est représentée par le mot clé Task nécessitant l’espace de nom System.Threadings.Task.

Le concept de Task dans le .NET Framework est un objet qui représente une opération qui doit être faite.

Une Task nous permet de savoir quand une opération est terminée mais aussi de retourner un résultat si nécessaire. Dans le cas où l’on souhaite que la Task nous renvoie une valeur, un type d’objet <T> doit être précisé. La syntaxe suivante sera donc utilisée : Task<T>.

Le cerveau, est un expert de l’utilisation des Tasks. Dans le sens où lorsque l’on écoute une musique il nous informe au moment du démarrage et de la fin de celle-ci.

Supposons que je demande à mon cerveau de me renvoyer la date du jour, voici la traduction en C# :

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
  
namespace TaskChapter 

   public static class Program 
    { 
       public static void Main() 
        { 
            Task<DateTime> DateDuJour = Task.Run(() => 
                { 
                    return DateTime.Today; 
                }); 
            Console.WriteLine(DateDuJour.Result); 
           //Résultat affiché : 17/03/2016 
        } 
    } 

Une Task contient plusieurs méthodes d’extensions. Nous avons par exemple : ContinueWith, WaitAll, WaitAny,..

Async et Await

Revenons sur notre hypothèse. Celle qui suppose que le cerveau ne puisse effectuer qu’une seule opération à la fois.

Dans une application informatique, ce serait l’équivalent d’avoir un écran qui reste figé tant que la fonctionnalité en cours d’exécution ne s’est pas achevée.

Par exemple, lorsque l’utilisateur clique sur le bouton « Enregistrer » d’un formulaire, tant que la sauvegarde des données en base n’est pas terminée, il ne pourra pas utiliser l’application car elle sera figée. Ce qui représente une mauvaise expérience utilisateur étant donné qu’une application informatique doit rester fluide et réactive.

Ce comportement est connu sous le nom de « blocage de processus ».

Techniquement parlant, c’est que toute activité liée à l’interface utilisateur partage généralement un thread. Lorsque celle-ci est longue elle fige l’UI (Interface Utilisateur).

Pour éviter ce genre de comportement, C# 5 nous offre la possibilité d’effectuer de la programmation asynchrone.

Au lieu que l’UI reste figée, l’utilisateur pourra continuer d’utiliser l’application jusqu’à ce que la tâche se termine.

Pour ce faire C# 5 dispose de deux mots clés : asyn et await pour écrire du code asynchrone.

Async permet d’informer le compilateur qu’un traitement en asynchrone s’effectuera sur la Task concernée.

Await permet d’attendre la fin de l’exécution de la tâche en question.

Voici un exemple de code C# en asynchrone :

public async Task<int> CalculateAnswer() 
       { 
           await Task.Delay(2000); 
           return 42; 
       }  

A noter que :

  • Le .NET Framework contient des méthodes qui sont par défaut en asynchrone. Nous avons par exemple : GetStringAsync()
  • Async et Await sont deux mots clés qui vont toujours ensemble. Ne jamais utiliser un async sans await et vice-versa. Sinon le traitement se fera en synchrone.
  • Eviter de renvoyer des Task de types void dans une méthode asynchrone sauf si c’est sur un évènement.

Voici un ensemble de liens vers des articles qui parlent de la programmation asynchrone :

Publicités