88 votes

Meilleure façon de convertir une méthode asynchrone basée sur un callback en tâche attendable

Quelle serait la meilleure façon de convertir/envelopper une méthode asynchrone "classique" qui utilise un callback en quelque chose qui renvoie une tâche (attendable) ?

Par exemple, étant donné la méthode suivante :

public void GetStringFromUrl(string url, Action<string> onCompleted);

La seule façon que je connaisse pour intégrer cela dans une méthode renvoyant une tâche est la suivante :

public Task<string> GetStringFromUrl(string url)
{
     var t = new TaskCompletionSource<string>();

     GetStringFromUrl(url, s => t.TrySetResult(s));

     return t.Task;
}

Est-ce le seul moyen d'y parvenir ?

Existe-t-il un moyen d'envelopper l'appel à GetStringFromUrl(url,callback) dans la tâche elle-même (c'est-à-dire que l'appel lui-même s'exécuterait dans la tâche au lieu d'être synchrone) ?

45voto

svick Points 81772

Votre code est court, lisible et efficace, donc je ne comprends pas pourquoi vous cherchez des alternatives, mais je n'en vois pas. Je pense que votre approche est raisonnable.

Je ne sais pas non plus pourquoi vous pensez que la partie synchrone est acceptable dans la version originale, mais que vous voulez l'éviter dans la version de l'UE. Task - à base d'eau. Si vous pensez que la partie synchrone peut prendre trop de temps, corrigez-la pour les deux versions de la méthode.

Mais si vous souhaitez l'exécuter de manière asynchrone (c'est-à-dire sur le ThreadPool ) uniquement dans le Task vous pouvez utiliser Task.Run() :

public Task<string> GetStringFromUrl(string url)
{
    return Task.Run(() =>
    {
        var t = new TaskCompletionSource<string>();

        GetStringFromUrl(url, s => t.TrySetResult(s));

        return t.Task;
    });
}

6voto

Drew Marsh Points 22002

Votre implémentation présumée est parfaitement bien pour cela, en supposant que le callback ne gère que des situations réussies. Que se passe-t-il actuellement si une exception se produit dans les fondements asynchrones de l'implémentation de GetStringFromUrl ? Il n'y a pas vraiment de moyen de la propager au callback de l'action... est-ce qu'il l'avale et vous renvoie null ou quelque chose comme ça ?

La seule chose que je recommande est de suivre la nouvelle convention consistant à nommer ces méthodes asynchrones avec le suffixe XXXAsync.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X