locked
Subscribe Unsubscribe Anonymous Delegate Chicken/Egg

    Question

  •  

    In the article "Subscribe to and Unsubscribe from Events"

    ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.en/dv_csref/html/6319f39f-282c-4173-8a62-6c4657cf51cd.htm

    it explains how "To subscribe to events by using an anonymous method".

    It points out the issue: "It is important to notice that you cannot easily unsubscribe from an event if you used an anonymous method to subscribe to it. To unsubscribe in this scenario, go back to the code where you subscribe to the event, store the anonymous method in a delegate variable, and then add the delegate to the event."

     

    The chicken/egg problem is when the delegate variable is unsubscribed from the event in the anonymous method, the compiler complains that the delegate variable is not initialized. Why?

     

    Please correct the following code example so that the compiler doesn't complain.

     

    One solution is to initialize the delegate variable to null.

     

    EventHandler<EventArgs> handler = null;

    handler = delegate(object sender, EventArgs args)

     

    Is there another solution?

     

    Grant

     

    =======================================

     

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    namespace PubSub

    {

    class Publisher

    {

    public EventHandler<EventArgs> PublisherEvent;

    public void DoIt()

    {

    if (PublisherEvent != null)

    PublisherEvent(this, new EventArgs());

    }

    }

    class Subscriber

    {

    public void MyEventHandler(object sender, EventArgs args)

    {

    Console.WriteLine(args);

    }

    public void DoIt(Publisher publisher)

    {

    EventHandler<EventArgs> handler = delegate(object sender, EventArgs args)

    {

    publisher.PublisherEvent -= handler;

    Console.WriteLine(args);

    };

    publisher.PublisherEvent += handler;

    publisher.DoIt();

    }

    }

    class Program

    {

    static void Main(string[] args)

    {

    Publisher pub = new Publisher();

    Subscriber sub = new Subscriber();

    sub.DoIt(pub);

    }

    }

    }

     

    Tuesday, November 13, 2007 3:00 AM

Answers

  • GE:

    Thanks for the feedback on the docs. I had to go back and read what I had written there (and look closely at your code).

    Actually, the compiler warning is occuring because you are unsubscribing from an event in your event handler itself! In other words, you are attempting to do something with "handler" before it has even been completely defined. If you intialize it to null, then you are just unsubscribing null from the event, which will always be a no-op.

     

    This example demonstrates how to create named delegate to store the value of the anonymous method. The code builds on the code in this related topic:

    http://msdn2.microsoft.com/en-us/library/w369ty8x(VS.80).aspx

     

    As you can see, if you need to unsubscribe to an event, you might as well just create a named delegate in the first place. Sorry for the confusion and I will clarify this in the documentation.

     

     

    class Subscriber2 : Subscriber

    {

    delegate void Temp<T>(object sender, CustomEventArgs e);

    EventHandler<CustomEventArgs> temp;

    public Subscriber2(string ID, Publisher pub)

    {

    id = ID;

    temp = delegate (object sender, CustomEventArgs e)

    {

    Console.WriteLine(id + " received this message: {0}", e.Message);

    };

    pub.RaiseCustomEvent += temp;

    }

    public void UnSubscribe(Publisher pub)

    {

    pub.RaiseCustomEvent -= temp;

    Console.WriteLine("Sub2 is unsubscribing");

    }

    }

     

    Michael Blome - MSFT

    Wednesday, November 14, 2007 6:54 PM

All replies

  • Hi,

     

    You have answered your own question.

    You have to assign it to null initially.

     

    Regards,

    Manju Sandhu

    Tuesday, November 13, 2007 10:02 AM
  • GE:

    Thanks for the feedback on the docs. I had to go back and read what I had written there (and look closely at your code).

    Actually, the compiler warning is occuring because you are unsubscribing from an event in your event handler itself! In other words, you are attempting to do something with "handler" before it has even been completely defined. If you intialize it to null, then you are just unsubscribing null from the event, which will always be a no-op.

     

    This example demonstrates how to create named delegate to store the value of the anonymous method. The code builds on the code in this related topic:

    http://msdn2.microsoft.com/en-us/library/w369ty8x(VS.80).aspx

     

    As you can see, if you need to unsubscribe to an event, you might as well just create a named delegate in the first place. Sorry for the confusion and I will clarify this in the documentation.

     

     

    class Subscriber2 : Subscriber

    {

    delegate void Temp<T>(object sender, CustomEventArgs e);

    EventHandler<CustomEventArgs> temp;

    public Subscriber2(string ID, Publisher pub)

    {

    id = ID;

    temp = delegate (object sender, CustomEventArgs e)

    {

    Console.WriteLine(id + " received this message: {0}", e.Message);

    };

    pub.RaiseCustomEvent += temp;

    }

    public void UnSubscribe(Publisher pub)

    {

    pub.RaiseCustomEvent -= temp;

    Console.WriteLine("Sub2 is unsubscribing");

    }

    }

     

    Michael Blome - MSFT

    Wednesday, November 14, 2007 6:54 PM