8

I've been working a lot with C# recently, and I've noticed that most code that raises events in my company's code is done like this:

EventHandler handler = Initialized;

if (handler != null)
{
    handler(this, new EventArgs());
}

I really don't understand why, instead, you can't do just do that:

if (Initialized != null)
{
    Initialized(this, new EventArgs());
}

EDIT:

Some food for thought, I tried doing a few tests on this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Test t = new Test(true);

            while(true)
            {
                t.Ev += new EventHandler(t_Ev);
                t.Ev -= new EventHandler(t_Ev);
            }
        }

        static void t_Ev(object sender, EventArgs e)
        {
        }
    }

    public class Test
    {
        private readonly bool m_safe;

        public Test(bool safe)
        {
            m_safe = safe;

            Thread t = new Thread(Go);
           t.Start();
        }

        private void Go()
        {
            while (true)
            {
                if(m_safe)
                {
                    RaiseSafe();
                }
                else
                {
                    RaiseUnsafe();
                }
            }
        }

        public event EventHandler Ev;

        public void RaiseUnsafe()
        {
            if(Ev != null)
            {
                Ev(this, EventArgs.Empty);
            }
        }

        public void RaiseSafe()
        {
            EventHandler del = Ev;

            if (del != null)
            {
                del(this, EventArgs.Empty);
            }
        }
    }
}

The Unsafe version makes the program crash.

user472875
  • 3,115
  • 4
  • 37
  • 68

2 Answers2

9

The first version is an attempt to make the event thread-safe.

See C# Events and Thread Safety

Actually, as said in the discussion, it doesn't make the event thread safe. Thus I would use the second version that is shorter instead.

EDIT: event thread-safety is really hard to implement. Look at what it might look... If you're not actually dealing with multiple threads that register/unregister events, you shouldn't waste time with thread-safety.

Community
  • 1
  • 1
ken2k
  • 48,145
  • 10
  • 116
  • 176
0

The second version is not thread-safe.

if (Initialized != null)
{
    Initialized(this, new EventArgs());
}

If the last handler unsubscribes after the if (Initialized != null) then you will end up with null ref exception.

VoodooChild
  • 9,776
  • 8
  • 66
  • 99
  • 3
    Actually neither version is threadsafe, depending on your definition of threadsafe. Sure, you can avoid the null dereference, but the first version does not avoid *potentially invoking a handler that has been removed on another thread.* – Eric Lippert Feb 17 '12 at 16:01