Having More Control over Delegate Chain Invocation

  1. What are the problems with calling delegates in a chain?
  2. How to avoid problems with calling delegates in a chain?

The first problem with calling delegates in a chain is that we can get only the last returned value.

The second problem with calling delegates in a chain is that if one of the delegates in a chain throws exception or runs too long other delegates won’t be called.

To avoid this problems we can use the GetInvocationList() method to get access to all delegates in a chain and call all methods explicitly.

Example 1:

    class Program

    {

 

        private string GetFirstStatus()

        {

            Trace.WriteLine("GetFirstStatus()");

            return "The first status returned";               

        }

 

        private string GetSecondStatus()

        {

            Trace.WriteLine("GetSecondStatus()");

            //If we wouldn’t use explicit invocation we wouldn’t be able

            //to call methods after this method.

            throw new InvalidOperationException("Exception was thrown");

        }

 

        private string GetThirdStatus()

        {

            Trace.WriteLine("GetThirdStatus()");

            return "The third status returned";

        }

 

 

        private void GetAllStatusesAnyway(GetStatus chain)

        {

            foreach (GetStatus status in chain.GetInvocationList())

            {

                try

                {

                    Trace.WriteLine(status());

                }

                catch(Exception ex)

                {

                    Trace.WriteLine(ex.Message);

                }

            }

        }

 

        private delegate String GetStatus();

 

        static void Main(string[] args)

        {

            GetStatus gsChain = null;

            Program program = new Program();

            gsChain += new GetStatus(program.GetFirstStatus);                                   

            gsChain += new GetStatus(program.GetSecondStatus);

            gsChain += new GetStatus(program.GetThirdStatus);

            try

            {

                Trace.WriteLine(gsChain());

            }

            catch(Exception){}

            program.GetAllStatusesAnyway(gsChain);      

    }

Output:

GetFirstStatus()

GetSecondStatus()

A first chance exception of type ‘System.InvalidOperationException’ occurred in ChainingProblem.exe

-==We can’t invoke the third delegate in the chain=-

GetFirstStatus()

The first status returned

GetSecondStatus()

A first chance exception of type ‘System.InvalidOperationException’ occurred in ChainingProblem.exe

Exception was thrown

GetThirdStatus()

The third status returned

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s