NullReferenceException when triggering event
Consider the following:
class Client
{
public static event EventHandler connectFailed;
private Socket socket;
public Client()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPo开发者_StackOverflow中文版int 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?
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.
Also in C# 6 you may do the null checking this way:
connectFailed?.Invoke(this, e);
Found it,
public delegate void OnRequestReceivedHandler(object sender);
public event OnRequestReceivedHandler ReqeustReceived = delegate { };
'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)
精彩评论