none
Events Delegates and how to consume them RRS feed

  • Question

  • I found the following code 

    public static class GCNotification
        {
            public static Action<Int32> s_gcDone = null;
            public static event Action<Int32> GCDone
            {
                add
                {
                    if (s_gcDone == null) { new GenObject(0); new GenObject(2); }
                    s_gcDone += value;
                }
                remove { s_gcDone -= value; }
            }
            private sealed class GenObject
            {
                private Int32 m_generation;
                public GenObject(Int32 generation) { m_generation = generation; }
                ~GenObject()
                {
                    if (GC.GetGeneration(this) >= m_generation)
                    {
                        Action<Int32> temp = Volatile.Read(ref s_gcDone);
                        if (temp != null) temp(m_generation);
                    }
                    if ((s_gcDone != null)
                            && !AppDomain.CurrentDomain.IsFinalizingForUnload()
                            && !Environment.HasShutdownStarted)
                    {
                        if (m_generation == 0) new GenObject(0);
                        else GC.ReRegisterForFinalize(this);
                    }
                    else { }
                }
            }
        }

    And I was told it would notify an event consumer class when a collection occurs. So, given that I am very inexperienced, I created the following class to consume the event:

    internal sealed class GListener
        {
            public GListener()
            {
                GCNotification.GCDone += HandleNotice;
            }
            private static void HandleNotice(Int32 gen)
            {
                Console.WriteLine($"Gen {gen} was just collected");
            }
        }

    Then I put the following in the Main() 

    public static void Main()
            {
                GListener Listner = new GListener();
                
                Timer t = new Timer(TimerCallback, null, 0, 2000);
                Console.ReadLine();
                t = null;
            }
            private static void TimerCallback(Object o)
            {
                Console.WriteLine("In TimerCallback:"+DateTime.Now);
                GC.Collect();
                
            }

    I get an output as follows: 
    In TimerCallback:1/13/2019 2:18:11 PM
    Gen 0 was just collected
    In TimerCallback:1/13/2019 2:18:13 PM
    Gen 0 was just collected
    Gen 2 was just collected
    In TimerCallback:1/13/2019 2:18:15 PM
    Gen 2 was just collected
    Gen 0 was just collected
    In TimerCallback:1/13/2019 2:18:17 PM
    Gen 0 was just collected
    Gen 2 was just collected

    So it seems to work, but I like to validate with someone that I consumed the event correctly. Frankly I am a bit unsure about how it works. I followed the guides online on how to consume the event, but I feel I don't fully understand it. more experienced and ask if I can get additional information about the collection. Like maybe a list of object names or something.


    • Edited by Zolfaghar Sunday, January 13, 2019 7:22 PM
    Sunday, January 13, 2019 7:19 PM

Answers

  • Yes, it looks perfectly fine. You consume the event by creating a method to act as a "handler" for the event, and then you add the handler using the "+=" operator. This is just what you did, so your code is correct.

    As a suggestion, don't bother adding t=null at the end of Main. It doesn't do anything at all; the variable t will be deallocated anyway as soon as Main exits, given that it is a local variable. You may be influenced by older code from VB, where it was recommended to set the variables to Nothing. In .NET, that recommendation is no longer appliccable.

    • Marked as answer by Zolfaghar Sunday, January 13, 2019 7:46 PM
    Sunday, January 13, 2019 7:33 PM
    Moderator

All replies

  • Yes, it looks perfectly fine. You consume the event by creating a method to act as a "handler" for the event, and then you add the handler using the "+=" operator. This is just what you did, so your code is correct.

    As a suggestion, don't bother adding t=null at the end of Main. It doesn't do anything at all; the variable t will be deallocated anyway as soon as Main exits, given that it is a local variable. You may be influenced by older code from VB, where it was recommended to set the variables to Nothing. In .NET, that recommendation is no longer appliccable.

    • Marked as answer by Zolfaghar Sunday, January 13, 2019 7:46 PM
    Sunday, January 13, 2019 7:33 PM
    Moderator
  • Thanks.
    Sunday, January 13, 2019 7:46 PM