Obtaining Return Values from Each Delegate in a Multicast Delegate






Obtaining Return Values from Each Delegate in a Multicast Delegate

Problem

You have added multiple delegates to a single multicast delegate. Each of these individual delegates returns a value that is required by your application. Ordinarily, the values returned by individual delegates in a multicast delegate are lostall except the value from the last delegate to fire, the return value of which is returned to the calling application. You need to be able to access the return value of each delegate that is fired in the multicast delegate.

Solution

Use the GetInvocationList method as in Recipe 9.1. This method returns each individual delegate from a multicast delegate. In doing so, you can invoke each delegate individually and get its return value. The following method creates a multicast delegate called All and then uses GetInvocationList to fire each delegate individually. After firing each delegate, the return value is captured:

	public static void TestIndividualInvokesRetVal()
	{
	    MyDelegate myDelegateInstance1 = new MyDelegate(TestInvoke.Method1);
	    MyDelegate myDelegateInstance2 = new MyDelegate(TestInvoke.Method2);
	    MyDelegate myDelegateInstance3 = new MyDelegate(TestInvoke.Method3);

	    MyDelegate allInstances =
	            myDelegateInstance1 +
	            myDelegateInstance2 +
	            myDelegateInstance3;

	    Console.WriteLine("Invoke individually (Obtain each return value):");
	    foreach (MyDelegate instance in allInstances.GetInvocationList())
	    {
	        int retVal = instance();
	        Console.WriteLine("\tOutput: " + retVal);
	    }
	}

The following delegate defines the MyDelegate delegate type:

	public delegate int MyDelegate( );

The following class contains each of the methods that will be called by the MyDelegate multicast delegate instances:

	public class TestInvoke
	{
	    public static int Method1( )
	    {
	        Console.WriteLine("Invoked Method1");
	        return (1);
	    }

	    public static int Method2( )
	    {
	        Console.WriteLine("Invoked Method2");
	        return (2);
	    } 
	    public static int Method3( )
	    {
	        Console.WriteLine("Invoked Method3");
	        return (3);
	    }
	}

Discussion

One quirk with multicast delegates is that if any or all delegates within its invocation list return a value, only the value of the last invoked delegate is returned; all others are lost. This loss can become annoying, or worse, if your code requires these return values. Consider a case in which the allInstances delegate was invoked normally, as in the following code:

	retVal = allInstances( );
	Console.WriteLine(retVal);

The value 3 would be displayed since Method3 was the last method invoked by the allInstances delegate. None of the other return values would be captured.

By using the GetInvocationList method of the MulticastDelegate class, you can get around this limitation. This method returns an array of Delegate objects that can each be invoked separately. Note that this method does not invoke each delegate; it simply returns an array of them to the caller. By invoking each delegate separately, you can retrieve each return value from each fired delegate. (More information on the GetInvocationList method is presented in Recipe 9.1.)

Note that any out or ref parameters will also be lost when a multicast delegate is invoked. This recipe allows you to obtain the out and/or ref parameters of each invoked delegate within the multicast delegate.

However, you still need to be aware that any unhandled exceptions emanating from one of these invoked delegates will be bubbled up to the method TestIndividualInvokesRetVal, presented in this recipe. To better handle this situation, see Recipe 9.3.

See Also

See Recipes 9.1 and 9.3; see the "Delegate Class" and "Delegate.GetInvocationList Method" topics in the MSDN documentation.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows