C # поднимая события - PullRequest
       2

C # поднимая события

8 голосов
/ 17 февраля 2012

В последнее время я много работал с C # и заметил, что большая часть кода, который вызывает события в коде моей компании, делается так:

EventHandler handler = Initialized;

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

Я действительно не понимаю, почему вместо этого вы не можете просто сделать это:

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

EDIT:

Пища для размышлений, я попытался сделать несколько тестов на этом:

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);
            }
        }
    }
}

Небезопасная версия вызывает сбой программы.

Ответы [ 2 ]

9 голосов
/ 17 февраля 2012

Первая версия - попытка сделать событие поточно-безопасным .

См. C # События и безопасность потоков

На самом деле, как сказано в обсуждении, поток событий не является безопасным. Таким образом, я бы использовал вторую версию, которая короче.

РЕДАКТИРОВАТЬ: безопасность потока событий действительно трудно реализовать. Посмотрите на как это может выглядеть ... Если вы на самом деле не имеете дело с несколькими потоками, которые регистрируют / отменяют регистрацию событий, вы не должны тратить время на безопасность потоков.

0 голосов
/ 17 февраля 2012

Вторая версия не является поточно-ориентированной.

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

Если последний обработчик отменит подписку после if (Initialized != null), вы получите исключение null ref.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...