TaskCompletionSource:Create Async functions on based event APIs

Dans cette article qui est en quelque sorte une seconde partie de TaskCompletionSource Fundamentals, nous parlerons sur comment encapsuler ou encore transformer des fonctionnalités d’une API orienté évènement en Tache asynchrone.

Quel est le problème ?

Dans la plupart des cas ils nous arrivent d’utiliser des librairies externes ou API voir certaines qui ont été directement traduit du non managé et managé voir du C/C++ à C++/CLI à C# et que dans ce cas le développeur de la librairie ne vous fournit que des évènement et non des fonctions asynchrones awaitable (async/await paru depuis C# 5.0) retournant des Task.

Mais pour illustrer cela nous allons utiliser la librairie NTwain vue dans l’article Scanner un document en C# permettant la capture par appareil photo digital ou scanner et essayer de revoir concrètement le dilemme.

  • Voilà donc pour commencer dans Nuget : Tapez NTwain
  • Dans une classe instancier un objet de type TwainSession et voyons un peu les évènements qu’il nous fournit :Dans ce cas la seule chose à faire afin de pouvoir afficher l’image renvoyer par Twain après la capture, serait de faire ceci :Et par la suite pour afficher notre image par exemple dans une PictureBox(en WinForm) nous ferons ceci :

Voilà tout ça (asynchronisme basé sur le Pattern Event Driven) c’est bien et notre application ne sera pas bloquante et fonctionnera parfaitement, car le scan est une assez longue procédure et si elle est lancée en tant qu’opération synchrone notre interface utilisateur sera figé et ne pourra rien faire d’autre.

Mais nous ne sommes pas satisfaits car ce code est vieux, pas efficace en tant qu’opération asynchrone.

Alors pour bien faire nous allons transformer notre API NTwain en asynchrone et en encapsulant tout ça dans une méthode asynchrone ScanDocumentAsync, prenant en paramètre un IntPtr qui est le Handle vers la fenêtre principale qui hébergera la boite de dialogue de progression de Twain et qui retourne un Task<string> (Tache asynchrone + le résultat qui le chemin d’accès complet de l’image en string).

Et alors comment créer une fonction asynchrone awaitable ?

Si vous avez bien appréhender le problème précèdent c’est que NTwain notre API ne nous offrez que des évènements et vu que le scan est un peu long, nous sommes contraints de créer nos propres méthodes asynchrones à partir des évènements qui nous sont proposer par NTwain, voilà une des plus grandes importances du TaskCompletion.

Dans ce cas la TaskCompletionSource nous permettra de créer une fonction asynchrone :

  • S’arrêtant et retournant une valeur juste après la fin de toute les opérations (SetResult)
  • Levant une Exception lors d’un échec de traitement quelconque. (SetException)
  • Annulable (SetCanceled)

Par rapport à la capture ci-haut, voici comment se crée une fonction asynchrone avec le TaskCompletionSource :

  • Instancier une TaskCompletionSource (TaskCompletionSource<TResult>)
  • Elaborer les scénarios d’arrêt possibles de votre fonction par rapport au SetResult, SetException et SetCanceled, et pour chaque cas créer un gestionnaire d’évènement et inscrivez le à l’évènement proprement dit. D’où à l’étape 2 nous avons créé un gestionnaire d’évènement inscrit à l’évènement DataTransferred qui récupère le chemin d’accès et déclenche le SetResult qui va aboutira directement à l’étape 4.
  • A l’étape 3 semble à la 2 mais cette fois nous créer un gestionnaire d’évènement par expression lambda que nous inscrivons à l’évènement TransferError et qui provoque l’arrêt de notre tâche asynchrone et lève une Exception.
  • Ici nous retournons tout simplement la Task générer par la TaskCompletionSource due à ses différentes méthodes qui sont 3 set ?

Projet complet de la démo NTwain : https://github.com/DanKyungu/NTwainScanProject

Espérant que cette article vous vraiment était d’une grande aide, à plus.

About Dan Kyungu

Check Also

Test Driven Development (C#)

Salut, Aujourd’hui nous parlerons sur le TDD (Test Driven Development). Le TDD est une méthodologie …

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *