Skip to content

C#使用自定义事件

SMS.cs,一个订阅者

using System; using System.Collections.Generic; using System.Text;

namespace EventExample { class SMS { public void OnNewMail(object sender, NewMailEventArgs e) { Console.WriteLine( "SMS Arrives: {0} to {1}, {2}", e.From, e.To, e.Subject); } } }

Phone.cs,另一个订阅者

using System; using System.Collections.Generic; using System.Text;

namespace EventExample { class Phone { public void OnNewMail(object sender, NewMailEventArgs e) { Console.WriteLine( "Phone Rings: {0} to {1}, {2}", e.From, e.To, e.Subject); } } }

NewMailEventArgs.cs,自定义的事件附加信息类

using System; using System.Collections.Generic; using System.Text;

namespace EventExample { class NewMailEventArgs : EventArgs { private readonly string m_from, m_to, m_subject;

    public NewMailEventArgs(string from, string to, string subject)
    {
        this.m_from = from;
        this.m_to = to;
        this.m_subject = subject;
    }

    public string From { get { return m_from; } }
    public string To { get { return m_to; } }
    public string Subject { get { return m_subject; } }
}

}

MailManager.cs,引发事件的类

using System; using System.Collections.Generic; using System.Text;

namespace EventExample { class MailManager { public event EventHandler<NewMailEventArgs> NewMail;

    protected virtual void OnNewMail(NewMailEventArgs e)
    {
        // For thread safe
        EventHandler<NewMailEventArgs> temp = NewMail;

        if (temp != null)
        {
            temp(this, e);
        }
    }

    public void SimulateNewMail(string from, string to, string subject)
    {
        NewMailEventArgs e = new NewMailEventArgs(from, to, subject);
        OnNewMail(e);
    }
}

}

这里的类使用了一个线程安全的做法,使用了一个OnNewMail虚方法调用事件,在调用之前首先将事件保存到一个temp中,这是因为确保事件不是null,如果直接判断NewMail是不是null,可能会在判断完之后,当时不是null,而紧接着被另一个线程修改成null,从而导致NullReferenceException的情况。

Program.cs

using System; using System.Collections.Generic; using System.Text;

namespace EventExample { class Program { static void Main(string[] args) { Phone phone = new Phone(); SMS sms = new SMS(); MailManager mailManager = new MailManager();

        mailManager.NewMail += phone.OnNewMail;
        mailManager.NewMail += sms.OnNewMail;

        for (int i = 0; i < 100; i++)
        {
            mailManager.SimulateNewMail(
                "Someone",
                "Someone else",
                "Test Mail" + i.ToString());
        }
    }
}

}