2010-03-12 95 views
5

我有一個ContextMenuStrip控件,允許您執行一個動作是兩種不同的風格:SyncAsync動作T同步和異步

我試圖掩蓋使用泛型所以我做了這一切:

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

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

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

我怎麼可以爲了執行通用的動作和「有所作爲」,在此期間的菜單寫異步方法? 我看到的BeginInvoke的簽名是這樣的:

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

回答

8

這裏是傑弗裏裏希特對.NET異步編程模型的文章。 http://msdn.microsoft.com/en-us/magazine/cc163467.aspx

這裏是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); 
    } 
} 

這裏是一個回調方法,可以傳遞給ExecAsync:

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

讓我看看 – Raffaeu 2010-03-12 16:57:08

+0

謝謝,這就是我一直在尋找的東西。我只是遇到了lambda表達式的一個問題,我不需要關於多線程編程的課程。 ;-) – Raffaeu 2010-03-12 17:23:47

+0

+1。傑夫的文章。這真的很有見地,幫了我很多。 – IAbstract 2010-12-31 15:21:16

2

簡單的選擇:

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