触发事件时出现 NullReferenceException

发布于 2024-11-02 18:41:50 字数 750 浏览 1 评论 0原文

请考虑以下事项:

class Client
{
    public static event EventHandler connectFailed;

    private Socket socket;

    public Client()
    {
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint endpoint = new IPEndpoint(
            IPAddress.Parse("192.168.1.100"),
            7900
            );

        try
        {
            socket.Connect(endpoint);
        }
        catch(Exception e)
        {
            connectFailed(e, new EventArgs());
        }
    }
}

假设其余代码已实现(Program.cs 中的事件处理程序等)。

我在 connectFailed(e, new EventArgs()); 行上遇到 NullRefrerenceException 问题,我不明白为什么。我的所有其他事件都运行得很好,我看不出这有什么不同。

有什么想法吗?

Consider the following:

class Client
{
    public static event EventHandler connectFailed;

    private Socket socket;

    public Client()
    {
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint endpoint = new IPEndpoint(
            IPAddress.Parse("192.168.1.100"),
            7900
            );

        try
        {
            socket.Connect(endpoint);
        }
        catch(Exception e)
        {
            connectFailed(e, new EventArgs());
        }
    }
}

Assume the rest of the code is implemented (Event handlers and such in Program.cs).

I am running into an issue with NullRefrerenceException on the connectFailed(e, new EventArgs()); line, and I can't understand why. All my other events are firing just fine, and I don't see how this is any different.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一枫情书 2024-11-09 18:41:50

您需要进行 null 检查 - 在 C# 中,当没有在该事件上注册处理程序时,您无法调用该事件。

正常的情况是实现 OnConnectFailed 方法:

protected virtual void OnConnectFailed(e as EventArgs) {
    EventHandler tmp = connectFailed;
    if(tmp != null)
        tmp(this,e);
}

此外,事件处理程序的第一个参数应该是 this,而不是异常。如果需要将异常传递给事件处理程序,请创建一个带有异常属性的 EventArgs 类。

另外,从构造函数引发事件是没有意义的……没有任何机会向其添加处理程序。

You need a null check - in C# you can't call events when there are no handlers registered on that event.

The normal thing would be to implement an OnConnectFailed method:

protected virtual void OnConnectFailed(e as EventArgs) {
    EventHandler tmp = connectFailed;
    if(tmp != null)
        tmp(this,e);
}

Also, the first argument to the event handler should be this, not the exception. If you need to pass the exception to the event handler, create an EventArgs class with an exception property.

Also, there's no point in raising an event from the constructor... nothing has a chance to add a handler to it.

§对你不离不弃 2024-11-09 18:41:50

同样在 C# 6 中,您可以通过以下方式进行空检查

connectFailed?.Invoke(this, e); 

Also in C# 6 you may do the null checking this way:

connectFailed?.Invoke(this, e); 
沙沙粒小 2024-11-09 18:41:50

找到了,

public delegate void OnRequestReceivedHandler(object sender);
public event OnRequestReceivedHandler ReqeustReceived = delegate { };

Found it,

public delegate void OnRequestReceivedHandler(object sender);
public event OnRequestReceivedHandler ReqeustReceived = delegate { };
合约呢 2024-11-09 18:41:50

“connectFailed”是一个事件。
如果没有人订阅该事件,则该事件将为 null,因此您必须检查 null 情况。

为了确保安全,您需要进行空检查,即:

if (connectFailed != null)
    connectFailed(e, new EventArgs()); 

但是,由于多线程,这种模式还不够。推荐的方法是这样的:

EventHandler temp = connectFailed;
if (temp != null)
    temp(e, new EventArgs()); 

这不仅检查 null 条件,而且首先复制事件以确保它是线程安全的(如果在另一个线程上处理事件时事件队列被一个线程更改,则该行为通过首先复制它,您可以确保订户列表在事件处理过程期间保持不变)

'connectFailed' is an event.
If nobody susbcribes to the event, it will be null, so you have to check for the null case.

To make this safe you would need a null check, i.e:

if (connectFailed != null)
    connectFailed(e, new EventArgs()); 

However, this pattern is not enough, because of multithreading. The recommended approach is this:

EventHandler temp = connectFailed;
if (temp != null)
    temp(e, new EventArgs()); 

This not only checks for the null condition, but also copies the event first to ensure it is thread-safe (if the event queue is changed by one thread while the event is being handled on another thread, the behaviour could be undefined. By copying it first you ensure that the subscriber list remains the same for the duration of the event-handling process)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文