2011-03-13 51 views
1

我繼承了一些冗長的重複代碼,我試圖重構。其中的裸骨頭如下:將代表類型委託給Delegate並調用EndInvoke

private void startThreads() 
{ 
    RunRemoteCmdDelegate runRemoteCmdDlg = new RunRemoteCmdDelegate(services.runRemoteCommand); 

    List<IAsyncResult> returnTags = new List<IAsyncResult>(); 

    // asynchronously invokes the delegate multiple times 
    foreach (...) 
    { 
     returnTags.Add(runRemoteCmdDlg.BeginInvoke(...)); 
    } 

    MonitorTasks(runRemoteCmdDlg, messages, returnTags, invokationCounter); 

} 

private void MonitorTasks(RunRemoteCmdDelegate theDelegate, List<IAsyncResult> returnTags) 
{ 

     foreach (IAsyncResult returnTag in returnTags) { 
      MessageType message = runRemoteCmdDlg.EndInvoke(returnTag); 
      messages.Add(message) 
     } 
} 

有許多類包含相同的代碼,但都有不同的委託類型。

我想「拉」的MonitorTasks方法爲基礎類,但它需要與各種不同類型的委託的工作,例如:

private void MonitorTasks(Delegate theDelegate, List<IAsyncResult> returnTags) 
{ 

     foreach (IAsyncResult returnTag in returnTags) { 
      MessageType message = runRemoteCmdDlg.EndInvoke(returnTag); // DOESN'T COMPILE 
      messages.Add(message) 
     } 
} 

我不能打電話基本Delegate(或MulticastDelegate)類型的EndInvoke(),那麼我該如何編寫此方法?我需要以不同的方式來解決這個問題嗎?我正在使用C#3.5,那麼有沒有辦法使用Func,Action等,並仍然能夠調用EndInvoke?

回答

1

您可以使用反射來訪問委託的EndInvoke()方法:

using System.Reflection; 

private void MonitorTasks(Delegate theDelegate, List<IAsyncResult> returnTags) 
{ 
    MethodInfo endInvoke = theDelegate.GetType().GetMethod("EndInvoke", 
     new Type[] { typeof(IAsyncResult) }); 
    foreach (IAsyncResult returnTag in returnTags) { 
     MessageType message = (MessageType) endInvoke.Invoke(theDelegate, 
      new object[] { returnTag }); 
     messages.Add(message); 
    } 
} 

爲見this blog更一般的,發射後不管採取這個問題。

+0

謝謝Frédéric,這很好。 – 2011-03-14 15:55:58