触发事件时NullReferenceException

时间:2014-12-10 00:22:00

标签: c# .net events nullreferenceexception

我有这个代码我正在玩,但它至少对我来说是一个奇怪的例外。

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

我不明白为什么它导致所述异常,因为我在另一个类中具有几乎相同的设置,工作正常。 此外,在使用变量检查器进行检查时,thise都已设置,因此不会为空。

我对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的航班没有?

2 个答案:

答案 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
相关问题