2010-03-12 20 views
5

Ich habe ein ContextMenuStrip-Steuerelement, mit dem Sie eine Aktion ausführen können, ist zwei verschiedene Varianten: Sync und Async.Aktion T synchron und asynchron

Ich versuche, alles unter Verwendung von Generics zu bedecken, so ich dies tat:

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

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

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

Wie ich von der Asynchron-Methode schreiben, um die generische Aktion und ‚etwas tun‘ mit dem Menü in der Zwischenzeit auszuführen? Ich sah, dass die Unterschrift von BeginInvoke so etwas wie ist:

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

Antwort

8

Hier ist Jeffrey Richter Artikel über .NET asynchrone Programmiermodell. Hier http://msdn.microsoft.com/en-us/magazine/cc163467.aspx

ist ein Beispiel dafür, wie BeginInvoke können verwendet werden:

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); 
    } 
} 

Und hier ist eine Callback-Methode, die auf die ExecAsync übergeben werden können:

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

lassen Sie mich einen Blick – Raffaeu

+0

Danke, das ist, was ich gesucht habe. Ich hatte nur ein Problem mit dem Lambda-Ausdruck, ich brauchte keinen Kurs auf Multithreading-Programmierung. ;-) – Raffaeu

+0

+1 für den ref. zu Jeffs Artikel. Das war sehr aufschlussreich und hat mir sehr geholfen. – IAbstract

2

Simplest Option:

// 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); 
     } 
    } 
} 
Verwandte Themen