2010-05-09 18 views
8

¿Hay alguna manera en que pueda hacer que un método de extensión sea asincrónico?Hacer un método de extensión asíncrona

He mirado alrededor desde hace un tiempo, pero todavía no he encontrado nada relacionado. Seguirá mirando sin embargo ...

+0

¿Qué quiere decir con el método asincrónico? – Dewfy

Respuesta

10

método Una extensión es sólo un método estático normal, con el azúcar sintáctica para invocarlo.

Así que descubra cómo se haría un método normal asíncrono (por ejemplo, iniciando una tarea dentro de él, en .NET 4) e ir desde allí.

7

Para hacer que cualquier método sea asíncrono envíe el método a una devolución de llamada y haga que el método gire un nuevo hilo.

me prepararon rápidamente una muestra corta en .NET 3.5 (tal vez Jon nos mostrará una muestra 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

Gracias por tu respuesta. :) –

2

En una nota relacionada tangencialmente, Reactive Extensions for .NET proporciona métodos de extensión que ayudan con la programación asincrónica. .NET 4 también tiene el Task Parallel Library (al que Jon aludió) que puede ayudar a paralelizar operaciones comunes en colecciones y, en general, simplifica en gran medida la propagación de excepciones (incluso la suma de excepciones en múltiples tareas), la coordinación entre múltiples tareas paralelas que deben combinar sus resultados. soporte para cancelaciones y otros comportamientos sofisticados.

4

Creo que están tratando de arreglar esto. De todos modos, es bastante fácil solucionarlo. Así es como se hace:

Digamos que el método asíncrono que estamos tratando de hacer en una extensión tiene este aspecto:

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

El VS no va a lanzar un ataque sobre esto, se compilará esta bien Sin embargo, si intenta llamar al "MyString".DoAsynchronousWork(), arrojará un error, diciendo que le falta un parámetro de cadena. Por lo tanto, no ignora por completo el hecho de que es una extensión, ¡pero aún requiere el parámetro "este"!

Afortunadamente, es fácil evitar esto. Basta con sustituir DoAsynchronousWork con esto:

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

espero que arreglar esto antes de liberar .NET 4.5, pero si no es así, por lo menos es fácil de solucionar. (Descubrí que las lambdas pueden ser asíncronas por accidente, pero ahora viene MUY útil!)

+0

Gracias, @ aboveyou00 por una respuesta valiosa. Upvote from me :-) Solo una actualización rápida para otros investigadores; "ellos" * consiguieron * esta falla corregida a tiempo para .NET 4.5, vea por ejemplo los métodos de extensión asincrónicos en [WindowsRuntimeStorageExtensions] (http://msdn.microsoft.com/en-us/library/hh582101.aspx) clase. –

Cuestiones relacionadas