I am receiving data from UdpClient via the usual async callback:
private void OnUdpData(IAsyncResult result)
{
byte[] data = _udpReceive.EndReceive(result, ref _receiveEndPoint);
//Snip doing stuff with data
_udpReceive.BeginReceive(OnUdpData, null);
}
When I Close()
the UdpClient in the main thread, the callback fires as I would expect, but at this point _udpReceive
is already disposed and I get an ObjectDisposedException
when I try and call EndReceive()
. I was expecting to just get an empty buffer.
What is the correct way to handle this? Is there some member of UdpClient
I can check before trying to use it, or it the only way to wrap it all in a try{}
and catch the ObjectDisposedException
? That seems pretty nasty for a normal close.
You can do this to check if its disposed. Client is set to null when the UdpClient is disposed.
private void OnUdpData(IAsyncResult result)
{
if (_udpReceive.Client == null)
return;
byte[] data = _udpReceive.EndReceive(result, ref _receiveEndPoint);
//Snip doing stuff with data
if (_udpReceive.Client == null)
return;
_udpReceive.BeginReceive(OnUdpData, null);
}
Although because you are closing it in a separate thread you may end up with a race condition. It would be best to just catch ObjectDisposedException and SocketException.
private void OnUdpData(IAsyncResult result)
{
try
{
byte[] data = _udpReceive.EndReceive(result, ref _receiveEndPoint);
//Snip doing stuff with data
_udpReceive.BeginReceive(OnUdpData, null);
}
catch (Exception e)
{
//You may also get a SocketException if you close it in a separate thread.
if (e is ObjectDisposedException || e is SocketException)
{
//Log it as a trace here
return;
}
//Wasn't an exception we were looking for so rethrow it.
throw;
}
}