Datapayasadas

abril 5, 2010

Una de eventos y suscriptores

Filed under: .Net, C#, Eventos — Matías @ 12:19 pm

Navegando por StackOverflow me encontré con una pregunta interesante de alguien que buscaba la forma de disparar eventos sin la necesidad de comprobar primero la existencia de suscriptores. Si no lo conocen al sitio, les recomiendo que le peguen una miradita porque es realmente útil, es sencillamente un sitio de preguntas y respuestas para programadores.

Volviendo al tema en sí, como ustedes saben, al disparar un evento en nuestra aplicación debemos primero comprobar que no sea null, lo cual indica que no hay ningún suscriptor para ese evento en particular. En caso de no realizar ésta comprobación, no podríamos disparar el evento sin luego recibir una excepción del tipo System.NullReferenceException.

Una forma alternativa que plantearon en StackOverflow, consiste en simplemente asignarle un delegado anónimo vacío al evento en el momento de su creación.

¿Cómo se hace?

Así:

public event EventHandler NombreDeNuestroEvento = delegate {};

¿Hay alguna contraindicación?

Aparentemente el costo, en performance, es muy pequeño … demasiado pequeño, a menos que estén realizando un sistema crítico que hace una utilización realmente importante de eventos. Hay una prueba de performance que pueden hacer para ver efectivamente el costo de utilizar un delegado anónimo vacío.

using System;
using System.Diagnostics;

class Program
{
    public event EventHandler<EventArgs> EventWithDelegate = delegate { };
    public event EventHandler<EventArgs> EventWithoutDelegate;

    static void Main(string[] args)
    {
        //warm up
        new Program().DoTimings(false);
        //do it for real
        new Program().DoTimings(true);

        Console.WriteLine("Done");
        Console.ReadKey();
    }

    private void DoTimings(bool output)
    {
        const int iterations = 50000000;

        if (output)
        {
            Console.WriteLine("For {0} iterations . . .", iterations);
        }

        //with anonymous delegate attached to avoid null checks
        var stopWatch = Stopwatch.StartNew();

        for (var i = 0; i < iterations; ++i)
        {
            RaiseWithAnonDelegate();
        }

        stopWatch.Stop();

        if (output)
        {
            Console.WriteLine("No null check (empty delegate attached): {0}ms", stopWatch.ElapsedMilliseconds);
        }

        //without any delegates attached (null check required)
        stopWatch = Stopwatch.StartNew();

        for (var i = 0; i < iterations; ++i)
        {
            RaiseWithoutAnonDelegate();
        }

        stopWatch.Stop();

        if (output)
        {
            Console.WriteLine("With null check (no delegates attached): {0}ms", stopWatch.ElapsedMilliseconds);
        }

        //attach delegate
        EventWithoutDelegate += delegate { };

        //with delegate attached (null check still performed)
        stopWatch = Stopwatch.StartNew();

        for (var i = 0; i < iterations; ++i)
        {
            RaiseWithoutAnonDelegate();
        }

        stopWatch.Stop();

        if (output)
        {
            Console.WriteLine("With null check (with delegate attached): {0}ms", stopWatch.ElapsedMilliseconds);
        }
    }

    private void RaiseWithAnonDelegate()
    {
        EventWithDelegate(this, EventArgs.Empty);
    }

    private void RaiseWithoutAnonDelegate()
    {
        var handler = EventWithoutDelegate;

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

Quedará en ustedes decidir si vale la pena o no utilizar este método. La diferencia es infinitesimal, unos pocos nanosegundos no van a matar a nadie … quiero creer.
Interesante, ¿no les parece?.

Hasta la próxima.

Anuncios

1 comentario »

  1. I’m amazed, I have to admit. Rarely do I encounter a blog that’s both educative and interesting, and let me tell you, you’ve hit the nail on the head.
    The problem is something which too few men and women are speaking intelligently about.
    I am very happy I came across this during my search for something regarding this.

    Comentario por Mellissa — diciembre 4, 2013 @ 6:56 pm


RSS feed for comments on this post. TrackBack URI

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Blog de WordPress.com.

A %d blogueros les gusta esto: