触发事件时出现 NullReferenceException
请考虑以下事项:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您需要进行 null 检查 - 在 C# 中,当没有在该事件上注册处理程序时,您无法调用该事件。
正常的情况是实现 OnConnectFailed 方法:
此外,事件处理程序的第一个参数应该是
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:
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 anEventArgs
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.
同样在 C# 6 中,您可以通过以下方式进行空检查:
Also in C# 6 you may do the null checking this way:
找到了,
Found it,
“connectFailed”是一个事件。
如果没有人订阅该事件,则该事件将为 null,因此您必须检查 null 情况。
为了确保安全,您需要进行空检查,即:
但是,由于多线程,这种模式还不够。推荐的方法是这样的:
这不仅检查 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:
However, this pattern is not enough, because of multithreading. The recommended approach is this:
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)