我有这个代码我正在玩,但它至少对我来说是一个奇怪的例外。
public class Flight
{
public class MessageEventArgs : System.EventArgs
{
public string msgContent;
}
public event System.EventHandler LogMessage;
public void StartFlight()
{
string tmpDeparture = this.Departure;
string tmpDestination = this.Destination;
this.OnLogUpdate("Taking off from " + tmpDeparture + " now.");
this.Destination = tmpDeparture;
Thread.Sleep(1000);
this.OnLogUpdate("Arriving in " + tmpDestination + " now.");
this.Departure = tmpDestination;
}
protected virtual void OnLogUpdate(string logMessage)
{
MessageEventArgs e = new MessageEventArgs();
if (logMessage == "")
return;
e.msgContent = logMessage;
LogMessage(this, e);
}
}
它会导致NullReferenceException, LogMessage(this,e);
我不明白为什么它导致所述异常,因为我在另一个类中具有几乎相同的设置,工作正常。
此外,在使用变量检查器进行检查时,this
和e
都已设置,因此不会为空。
我对C#来说还是一个新手,特别是事件和代表,所以我可能错过了或多或少明显的东西
[编辑]
如果是因为事件没有订阅,那么这有什么问题?
public partial class MainForm : Form
{
Airport airport = new Airport();
Flight flight = new Flight();
public MainForm()
{
InitializeComponent();
InitializeEvents();
}
private void InitializeEvents()
{
this.airport.ErrorMessage += new System.EventHandler(OnErrorReceived);
this.flight.LogMessage += new System.EventHandler(OnLogReceived);
}
机场错误消息的订阅工作正常,但是LogMessage的航班没有?
答案 0 :(得分:2)
LogMessage是一个事件,未被其他类订阅。你应该在触发它之前检查它是否为空
if (LogMessage != null)
{
LogMessage(this, e);
}
答案 1 :(得分:2)
我建议将此行添加到您的Flight
对象构造函数
LogMessage += (s, o) => {};
这将为您的事件添加一个虚拟处理程序,您可以使用它而不必每次检查它的可空性,但它有很高的开销,如果有人将LogMessage
设置为null然后繁荣! NullPointerException
。
另一个选择是每次要发起事件时检查是否为空,
if(LogMessage != null)
{
LogMessage(this, e);
}
但是当线程A检查LogMessage
是否为空并且它不为空并且线程B将LogMessage
设置为null然后线程A触发{{}时,这可以在多线程场景中产生竞争条件1}}和繁荣! LogMessage
最好的方法就是这样做
NullPointerException