2012-07-09 54 views
4

Inisde BeginInvoke,AsyncResult.AsyncDelegate後回調需要被轉換爲適當的類型,只有然後EndInvoke是可訪問的。c#調用endallvoke在回調,使用泛型

但我使用泛型,所以我需要爲N個廣義方法定義N個回調?

這是類:

public class Async 
    { 
     public delegate object Func(); //void with no parameter 
     public delegate TResult Func<T, TResult>(T arg); //one parameter with result 

     public static void Execute(IAsyncSubscriber subscriber, Func action) 
     { 
      action.BeginInvoke(Callback, subscriber); 
     } 

     public static void Execute<T, T1>(IAsyncSubscriber subscriber, T param, Func<T, T1> action) 
     { 
      action.BeginInvoke(param, Callback, subscriber); 
     } 

     private static void Callback(IAsyncResult ar) 
     { 
      AsyncResult result = (AsyncResult)ar; 
      IAsyncSubscriber subscriber = (IAsyncSubscriber)result.AsyncState; 
      Func action = (Func) result.AsyncDelegate; 
      object returnValue = action.EndInvoke(result); //To call endinvoke 
      subscriber.Callback(returnValue); 
     } 
    } 
+2

如果我理解正確的話,你的假設是正確的。您將需要定義'N'回調。在光明的一面,你只會做這一次,所以沒有biggy,只是一個重複的工作:) – leppie 2012-07-09 10:19:53

+1

好的,謝謝!你可以移動你的評論來回答,我會關閉這個。 – 2012-07-09 10:37:40

回答

4

有幾種方法,使您能夠避免設N回調:

  1. 您可以在BeginInvoke調用中將相應的EndInvoke方法作爲狀態傳遞。例如

    private delegate T EndInvokeDelegate<T>(IAsyncResult ar); 
    
    public static void Execute<T, T1>(IAsyncSubscriber subscriber, T param, Func<T, T1> action) 
    { 
        action.BeginInvoke(param, Callback<T1>, new object[]{subscriber, new new EndInvokeDelegate<T1>(action.EndInvoke)}); 
    } 
    
    public static void Execute<T, T1, T2>(IAsyncSubscriber subscriber, T param1, T1 param2, Func<T, T1, T2> action) 
    { 
        action.BeginInvoke(param1, param2, Callback<T2>, new object[]{subscriber, new new EndInvokeDelegate<T2>(action.EndInvoke)}); 
    } 
    
    private static void Callback<TR>(IAsyncResult ar) 
    { 
        object[] stateArr = (object[])ar.AsyncState; 
        IAsyncSubscriber subscriber = (IAsyncSubscriber)stateArr[0]; 
        EndInvokeDelegate<TR> action = (EndInvokeDelegate<TR>)stateArray[1]; 
        TR returnValue = action(ar); 
        subscriber.Callback(returnValue); 
    }  
    

    您也可以回調非通用的治療stateArray [1] MultiCastDelegate並使用它DynamicInvoke但是這將是緩慢的。

  2. 對於.Net 2.0和3.0,您可以使用反射

    Type actionType= result.AsyncDelegate.GetType(); 
    var minfo = actionType.GetMethod("EndInvoke"); 
    object returnValue = minfo.Invoke(res.AsyncDelegate, new object[] { ar }); 
    
  3. 對於.Net 4.0,您可以使用動態。例如

    dynamic action = result.AsyncDelegate; 
    object returnValue = action.EndInvoke(result); 
    
+0

謝謝。但它的標籤C#2.0。用反射調用方法很不理想 – 2012-07-10 11:26:06

+0

你是對的...我的不好...但點沒有3仍然擁有:) – 2012-07-10 11:26:50

+0

更新我的編輯。 thx, – 2012-07-10 11:28:03

1

如果我理解正確的話,你的假設是正確的。您將需要定義N回調。

在光明的一面,你只會一次這樣做,所以沒有biggy,只是有點重複的工作:)

+0

艾米特做到了!它的工作! – 2012-07-11 04:16:52