2011-03-13 7 views
1

私はリファクタリングしようとしている冗長なコードを継承しました。デリゲートにデリゲート型をキャストして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) 
     } 
} 

私は呼び出すことはできませんEndInvoke()をベースのDelegate(またはMulticastDelegate)型で使用すると、このメソッドをどのように記述できますか?私は別の方法でこれにアプローチする必要がありますか?

私は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

ありがとうフレデリック、うまくいきます。 –