C#使用自定义事件

SMS.cs,一个订阅者
[sourcecode language=’c#’]
using System;
using System.Collections.Generic;
using System.Text;

namespace EventExample
{
class SMS
{
public void OnNewMail(object sender, NewMailEventArgs e)
{
Console.WriteLine(
“SMS Arrives: [NEW MAIL] {0} to {1}, {2}”,
e.From, e.To, e.Subject);
}
}
}
[/sourcecode]

Phone.cs,另一个订阅者
[sourcecode language=’c#’]
using System;
using System.Collections.Generic;
using System.Text;

namespace EventExample
{
class Phone
{
public void OnNewMail(object sender, NewMailEventArgs e)
{
Console.WriteLine(
“Phone Rings: [NEW MAIL] {0} to {1}, {2}”,
e.From, e.To, e.Subject);
}
}
}
[/sourcecode]

NewMailEventArgs.cs,自定义的事件附加信息类
[sourcecode language=’c#’]
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; } }
}
}
[/sourcecode]

MailManager.cs,引发事件的类
[sourcecode language=’c#’]
using System;
using System.Collections.Generic;
using System.Text;

namespace EventExample
{
class MailManager
{
public event EventHandler NewMail;

protected virtual void OnNewMail(NewMailEventArgs e)
{
// For thread safe
EventHandler 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);
}
}
}
[/sourcecode]

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

Program.cs
[sourcecode language=’c#’]
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()); } } } } [/sourcecode]

发表评论