Multithreading

Dans la première partie, nous avons étudié les threads et les tasks. Le framework .NET propose d’autres outils pour faire du multithreading. Dans cette deuxième partie, nous verrons la classe Parallel et les mots clés async et await.

La classe Parallel

Le namespace System.Threading.Tasks propose également la classe Parallel pour lancer des traitements en parallèle. Pour cela, on utilise les méthodes statiques For et ForEach. Elles permettent d’exécuter des boucles en parallèle.

static void Main(string[] args)
{
    Parallel.For(0,1000, (x)=>Console.WriteLine(x));
}

Multithreading - classe Parallel

async et await

C# 5 a introduit deux nouveaux mots clé utilisés pour le multithreading : async et await. async est utilisé pour signifier qu’une méthode contient du code asynchrone. Si une méthode est marquée async sans code asynchrone, il n’y a pas d’erreur, juste un warning. await marque le début de l’opération asynchrone. Il peut y en avoir plusieurs dans une méthode. Un exemple de traitement asynchrone est l’accès à un fichier ou à une ressource en ligne.

static void Main(string[] args)
{
    Task.Run(DownloadContent);
}

public static async Task DownloadContent()
{
    string result = "";
    using (HttpClient client = new HttpClient())
    {
        result = await client.GetStringAsync("http://www.google.com");
    }

    Console.WriteLine(result);
}

Par convention, les méthodes asynchrones utilisent le suffixe Async, par exemple GetStringAsync. Lorsqu’une méthode async retourne une valeur de type Result, son type de retour est Task<Result>.

Ainsi, si ma méthode retourne un string, son type de retour sera Task<string>. Si la méthode n’a pas de type de retour, on utilise Task ou void.

Gestion des exceptions

Pour « catcher » une exception qui a eu lieu dans un appel asynchone, il suffit d’entourer cet appel d’un try catch comme on le ferait avec n’importe qu’elle méthode.

static void Main(string[] args)
{
    Task.Run(MaMethode);
    Console.ReadKey();
}

static async Task MaMethode()
{
    try
    {
        await DoSomethingAsync();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

static Task DoSomethingAsync()
{
    throw new Exception();
}

Multithreading - gestion des exceptions

Il peut arriver qu’un appel asynchrone retourne plusieurs exceptions. C’est le cas lorsqu’on utilise WhenAll ou la classe Parallel. Pour ces cas, le Framework .NET propose la classe AggregateException qui permet de gérer plusieurs exceptions. Elle possède une propriété InnerExceptions qui est une collection de toutes les exceptions « catchées ».

static void Main(string[] args)
{
    Task task1 = new Task(() =>
    {
        throw new IndexOutOfRangeException();
    });

    Task task2 = new Task(() =>
    {
        throw new Exception();
    });

    Task task3 = new Task(() =>
    {
        throw new InvalidOperationException();
    });

    task1.Start();
    task2.Start();
    task3.Start();

    try
    {
        Task.WaitAll(task1, task2, task3);
    }
    catch (AggregateException aex)
    {
        foreach (var inner in aex.InnerExceptions)
        {
            Console.WriteLine("Exception type: {0}", inner.GetType());
            Console.WriteLine("Message: {0}", inner.Message);
        }
    }
    Console.ReadKey();
}

Multithreading - exceptions 2

Voilà! cette deuxième partie nous a permis d’en voir plus sur les outils qu’offre le Framework .NET pour gérer le multithreading. Dans la troisième partie nous verrons comment annuler une opération asynchrone et voir sa progression.

Auteur : Daniel MINKO FASSINOU

Laisser un commentaire




Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.