2010-03-12 8 views
5

Tengo un control ContextMenuStrip que le permite ejecutar una acción con dos sabores diferentes: Sync y Async.Acción T síncrona y asíncrona

estoy tratando de cubrir todo el uso de los genéricos, así que hice esto:

public class BaseContextMenu<T> : IContextMenu 
{ 
    private T executor; 

    public void Exec(Action<T> action) 
    { 
     action.Invoke(this.executor); 
    } 

    public void ExecAsync(Action<T> asyncAction) 
    { 
     // ... 
    } 

¿Cómo puedo escribir el método asíncrono con el fin de ejecutar la acción genérica y 'hacer algo' con el menú en el ínterin? vi que la firma de BeginInvoke es algo así como:

asyncAction.BeginInvoke(this.executor, IAsyncCallback, object); 

Respuesta

8

Aquí está el artículo de Jeffrey Richter el modelo de programación asíncrona .NET. http://msdn.microsoft.com/en-us/magazine/cc163467.aspx

Aquí es un ejemplo de cómo se puede utilizar BeginInvoke:

public class BaseContextMenu<T> : IContextMenu 
{ 
    private T executor; 

    public void Exec(Action<T> action) 
    { 
     action.Invoke(this.executor); 
    } 

    public void ExecAsync(Action<T> asyncAction, AsyncCallback callback) 
    { 
     asyncAction.BeginInvoke(this.executor, callback, asyncAction); 
    } 
} 

Y aquí es un método de devolución de llamada que se puede pasar a la ExecAsync:

private void Callback(IAsyncResult asyncResult) 
{ 
    Action<T> asyncAction = (Action<T>) asyncResult.AsyncState; 
    asyncAction.EndInvoke(asyncResult); 
} 
+0

déjame echar un vistazo – Raffaeu

+0

Gracias, esto es lo que estaba buscando. Solo tuve un problema con la expresión lambda, no necesité un curso sobre programación multiproceso. ;-) – Raffaeu

+0

+1 para la ref. al artículo de Jeff. Eso fue realmente perspicaz y me ayudó mucho. – IAbstract

2

opción más simple:

// need this for the AsyncResult class below 
using System.Runtime.Remoting.Messaging; 

public class BaseContextMenu<T> : IContextMenu 
{ 
    private T executor; 

    public void Exec(Action<T> action) { 
     action.Invoke(this.executor); 
    } 

    public void ExecAsync(Action<T> asyncAction) { 
     // specify what method to call when asyncAction completes 
     asyncAction.BeginInvoke(this.executor, ExecAsyncCallback, null); 
    } 

    // this method gets called at the end of the asynchronous action 
    private void ExecAsyncCallback(IAsyncResult result) { 
     var asyncResult = result as AsyncResult; 
     if (asyncResult != null) { 
      var d = asyncResult.AsyncDelegate as Action<T>; 
      if (d != null) 
       // all calls to BeginInvoke must be matched with calls to 
       // EndInvoke according to the MSDN documentation 
       d.EndInvoke(result); 
     } 
    } 
} 
Cuestiones relacionadas