首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UdpClient.CancelReceive在哪?

UdpClient.CancelReceive在哪?
EN

Stack Overflow用户
提问于 2009-05-08 14:35:21
回答 2查看 2.9K关注 0票数 4

我正在实现一个简单的本地网络发现协议,所以我先调用UdpClient.Send,然后调用UdpClient.BeginReceive。如果有多个响应挂起,我会在回调结束时调用UdpClient.BeginReceive。如下所示:

代码语言:javascript
复制
UdpClient client = new UdpClient(AddressFamily.InterNetwork);
client.EnableBroadcast = true;
client.Send(request, request.Length, broadcastEndPoint);
client.BeginReceive(Callback, client);

然后在Callback中使用...and

代码语言:javascript
复制
void Callback(IAsyncResult ar)
{
    UdpClient client = (UdpClient)ar.AsyncState;
    IPEndPoint remoteEndPoint = null;
    byte[] response = client.EndReceive(ar, ref remoteEndPoint);

    // Do something with response

    client.BeginReceive(Callback, client);
}

我的问题是,我的主循环在接收挂起时调用client.Close。接收完成,然后我对BeginReceive的下一次调用抛出一个异常:System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host

为什么UdpClient没有CancelReceive方法?我能做些什么呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-16 00:00:20

使用"isClosing“标志来通知回调函数该UdpClient不再可用不是一个合适的解决方案。当回调在不同的线程中执行时,连接总是有可能在"isClosing“标志检查之后、"BeginReceive”(或"EndReceive")调用之前关闭。

尽管这不是一个干净的设计,但微软似乎建议只捕获相应的异常来检测套接字不再可用。没有记录"BeginReceive",但这就是documented for the similar function "BeginConnect"

若要取消对BeginConnect()方法的挂起调用,请关闭套接字。当异步操作正在进行时调用Close()方法时,将调用提供给BeginConnect()方法的回调。随后对EndConnect(IAsyncResult)方法的调用将抛出一个ObjectDisposedException,以指示操作已被取消。

因此,示例代码将如下所示:

代码语言:javascript
复制
void Callback(IAsyncResult ar)
{
    try
    {
        UdpClient client = (UdpClient)ar.AsyncState;
        IPEndPoint remoteEndPoint = null;
        byte[] response = client.EndReceive(ar, ref remoteEndPoint);

        // Do something with response

        client.BeginReceive(Callback, client);
    }
    catch (SocketException e)
    {
        // Oups, connection was closed
    }
    catch (ObjectDisposedException e)
    {
        // Oups, client was disposed
    }
}
票数 3
EN

Stack Overflow用户

发布于 2009-09-08 07:16:38

相反,要克服此异常,请在发出close命令之前创建bool并设置它,使用bool签入回调

像这样

代码语言:javascript
复制
bool isClosing=false;
void Callback(IAsyncResult ar)
{
    if(isClosing) return;
}

在发出close命令之前设置bool isClosing

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/840090

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档