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