c# - 我如何知道 UdpClient 是否已关闭/处置?

标签 c# asynchronous dispose udpclient

我正在通过通常的异步回调从 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/

相关文章:

java - Java 会自动异步调用这些方法吗?

javascript - 如何避免使用异步服务重复填充数组

c# - 如何处理 ManualResetEvent

c# - 处理 LINQ to SQL DataContext 有什么好处?

c# - 将参数传递给 linq 谓词

c# - 以编程方式添加控件时未实例化占位符

c# - 与thread.sleep一起使用时如何在无限循环中执行多个任务

c# - 响应门控下一条消息发送,使用 Rx

c# - EF4 代码优先 : how to update specific fields only

c# - 序列化和反序列化时如何正确处理流处置和定位