I have inherited some verbose, repetitious code that I am trying to refactor. The bare bones of which are as follows:
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)
}
}
There are many classes containing this same code but all with different delegate types.
I’d like to ‘pull up’ the MonitorTasks method into a base class, but it will need to work with all the different types of delegate, for example:
private void MonitorTasks(Delegate theDelegate, List<IAsyncResult> returnTags)
{
foreach (IAsyncResult returnTag in returnTags) {
MessageType message = runRemoteCmdDlg.EndInvoke(returnTag); // DOESN'T COMPILE
messages.Add(message)
}
}
I can’t call EndInvoke() on the base Delegate (or MulticastDelegate) type, so how can I code this method? Do I need to approach this in a different way?
I’m using C#3.5, so is there some way to use Func, Action, etc, and still be able to call EndInvoke?
You can use reflection to access the
EndInvoke()method of the delegate:See this blog for a more general, fire-and-forget take on the problem.