我正在通过通常的异步回调从 UdpClient 接收数据:
private void OnUdpData(IAsyncResult result)
{
byte[] data = _udpReceive.EndReceive(result, ref _receiveEndPoint);
//Snip doing stuff with data
_udpReceive.BeginReceive(OnUdpData, null);
}
当我 Close()
主线程中的 UdpClient 时,回调将如我所料触发,但此时 _udpReceive
已经处理完毕,我得到一个 ObjectDisposedException
当我尝试调用 EndReceive()
时。我原以为只会得到一个空缓冲区。
处理这个问题的正确方法是什么?是否有 UdpClient
的一些成员我可以在尝试使用它之前检查它,或者它是将它全部包装在 try{}
中并捕获 ObjectDisposedException 的唯一方法
?对于正常的关闭来说,这似乎很糟糕。
最佳答案
您可以执行此操作以检查其是否已处置。处理 UdpClient 时,Client 设置为 null。
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);
}
虽然因为你在一个单独的线程中关闭它,你可能会以竞争条件结束。最好只捕获 ObjectDisposedException 和 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;
}
}
关于c# - 我如何知道 UdpClient 是否已关闭/处置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9310417/