[英]Question about custom events
我正在為C#制作自定義事件,有時它不起作用。
這就是我讓事件發生的方式:
private bool isDoorOpen;
public bool IsDoorOpen {
get { return isDoorOpen;}
private set { isDoorOpen = value; DoorsChangeState(this, null);}
}
這些是事件聲明:
//events
public delegate void ChangedEventHandler(Elevator sender, EventArgs e);
public event ChangedEventHandler PositionChanged;
public event ChangedEventHandler DirectionChanged;
public event ChangedEventHandler BreaksChangeState;
public event ChangedEventHandler DoorsChangeState;
只要有事件附加了方法,這就可以工作,但如果沒有,則會拋出空引用異常。 我究竟做錯了什么?
調用事件的推薦方法是
var handler = this.DoorsChangeState;
if (handler != null)
handler(this, null);
在本地復制處理程序的原因是當您檢查null時,在另一個線程上更改事件處理程序。
編輯:發現文章談論競爭條件。 http://blogs.msdn.com/ericlippert/archive/2009/04/29/events-and-races.aspx
我知道這個問題已經在SO上多次討論(並得到了回答)。
在這里的某處我有以下擴展方法,使這個模式更容易使用:
public static class EventHandlerExtensions
{
public static void FireEvent<T>(this EventHandler<T> handler, object sender, T args) where T : EventArgs
{
var temp = handler;
if (temp != null)
{
temp(sender, args);
}
}
public static void FireEvent(this EventHandler handler, object sender)
{
var temp = handler;
if (temp != null)
{
temp(sender, EventArgs.Empty);
}
}
}
所以在你的代碼中你可以說:
public bool IsDoorOpen
{
get { return isDoorOpen;}
private set
{
isDoorOpen = value;
DoorsChangeState.FireEvent(this);
}
}
如果事件在觸發時未訂閱,則將拋出NullReferenceException。 這是正確的行為,而不是你做錯了。
你應該檢查:
if(DoorsChangeState != null)
{
DoorsChangeState(this, null); // Only fire if subscribed to
}
在調用事件之前,您必須檢查事件是否為null:
if (DoorsChangeState != null)
DoorsChangeState(this, null);
當DoorsChangeState
為null時,表示該事件上沒有偵聽器。
您需要檢查事件是否已訂閱。
我使用這個標准形式來拋出我的所有事件。
var temp = EventName;
if(EventName!= null)
temp(this, null);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.