2010-05-09 5 views
8

Est-il possible de rendre une méthode d'extension asynchrone?Création d'une méthode d'extension asynchrone

J'ai regardé autour depuis un moment maintenant, mais n'ai pas encore trouvé quelque chose en rapport. Continuera à chercher ...

+0

Que voulez-vous dire à propos de la méthode asynchrone? – Dewfy

Répondre

10

Une méthode d'extension est juste une méthode statique normale, avec du sucre syntaxique pour l'appeler.

Donc, étudiez comment vous pouvez rendre une méthode normale normale asynchrone (par exemple en démarrant une tâche à l'intérieur de celle-ci, dans .NET 4) et partir de là.

7

Pour rendre une méthode asynchrone, envoyez un rappel à la méthode et faites tourner la nouvelle méthode par la méthode.

Je fouetté un court échantillon dans .net 3.5 (peut-être Jon va nous montrer un échantillon 4.0):

public static void Extension<T>(this T self, AsyncCallback callback) 
    { 
     var state = new State { callback = callback }; 
     System.Threading.ThreadPool.QueueUserWorkItem(ExtensionCore, callback); 
    } 

    private static void ExtensionCore(object state) 
    { 
     // do stuff with OtherStuff 
     var complete = new Complete(); 
     ((State)state).callback(complete); 
    } 

    private class State 
    { 
     public AsyncCallback callback { get; set; } 
     public object OtherStuff { get; set; } 
    } 

    public class Complete : IAsyncResult 
    { 
     public object AsyncState 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public System.Threading.WaitHandle AsyncWaitHandle 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public bool CompletedSynchronously 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public bool IsCompleted 
     { 
      get { throw new NotImplementedException(); } 
     } 
    } 
} 
+0

Merci pour votre réponse. :) –

2

Sur une note liée tangentiellement, Reactive Extensions for .NET fournit des méthodes d'extension qui facilitent la programmation asynchrone. .NET 4 a aussi le Task Parallel Library (auquel Jon a fait allusion) qui peut aider à paralléliser les opérations courantes sur les collections et simplifie grandement la propagation des exceptions (même en regroupant les exceptions sur plusieurs tâches), coordination entre plusieurs tâches parallèles qui doivent combiner leurs résultats, soutien à l'annulation et autres comportements sophistiqués.

4

Je pense qu'ils essaient de résoudre ce problème. C'est assez facile de contourner, de toute façon. Voilà comment vous le faites:

Disons que la méthode async que vous essayez de faire en une extension ressemble à ceci:

public static async Task DoAsynchronousWork(this string doWorkTo) 
{ 
    await AnotherAsyncFunctionAsync(doWorkTo); 
    await DoSomeOtherWorkAsync(doWorkTo); 
    await DoMoreWorkAsync(doWorkTo); 
} 

Le VS ne lancera pas un ajustement à ce sujet, il compilera ça va. Toutefois, si vous essayez d'appeler "MyString".DoAsynchronousWork(), une erreur se produit, indiquant qu'il manque un paramètre de chaîne. Donc, il n'ignore pas complètement le fait qu'il s'agit d'une extension, mais il nécessite toujours le paramètre "this"!

Heureusement, il est facile de contourner ce problème. Il suffit de remplacer DoAsynchronousWork par ceci:

public static Task DoAsynchronousWork(this string doWorkTo) 
{ 
    return new Task(async() => { 
     await AnotherAsyncFunctionAsync(doWorkTo); 
     await DoSomeOtherWorkAsync(doWorkTo); 
     await DoMoreWorkAsync(doWorkTo); 
    }); 
} 

J'espère qu'ils obtiennent avant que ce soit réglé la version 4.5 .NET, mais sinon, au moins il est facile de travailler autour. (J'ai découvert que les lambdas peuvent être asynchrones par accident, mais maintenant ça arrive TRÈS à portée de main!)

+0

Merci, @ aboveyou00 pour une réponse précieuse. Upvote de moi :-) Juste une mise à jour rapide pour d'autres chercheurs; "ils" ont * obtenu * cette faille corrigée à temps pour .NET 4.5, voir par exemple les méthodes d'extension asynchrones dans [WindowsRuntimeStorageExtensions] (http://msdn.microsoft.com/en-us/library/hh582101.aspx) classe. –

Questions connexes