首页 文章

C#TCP Async EndReceive()仅在Windows XP 32位上抛出InvalidOperationException

提问于
浏览
2

我有一个使用.NET套接字的简单C#Async Client,它等待来自用于自动执行命令的本地Java服务器的定时消息 . 消息以异步方式进入,并写入环形缓冲区 . 此实现似乎在Windows Vista / 7/8和OSX上正常工作,但在从本地Java服务器接收消息时会随机抛出此异常:

未处理的异常:System.InvalidOperationException:只能为每个异步操作调用一次EndReceive . 在System.Net.Sockets.Socket.Socket.EndReceive(IAsyncResult asyncResult,SocketError&errorCode)的System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)处于SocketTest.Controller.RecvAsyncCallback(IAsyncResult ar)的System.Net.LazyAsyncResult.Complete( IntPtr userToken)...

我在网上看到了这个错误,但没有发现任何真正有用的东西 . 这是它似乎破坏的代码:

/// <summary>
/// Callback to receive socket data
/// </summary>
/// <param name="ar">AsyncResult to pass to End</param>
private void RecvAsyncCallback(IAsyncResult ar)
{
    // The exception will randomly happen on this call
    int bytes = _socket.EndReceive(_recvAsyncResult);

    // check for connection closed
    if (bytes == 0)
    {
        return;
    }

    _ringBuffer.Write(_buffer, 0, bytes);

    // Checks buffer
    CheckBuffer();

    _recvAsyncResult = _sock.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, RecvAsyncCallback, null);
}

除了在接收消息的过程中,该错误不会发生在任何特定时刻 . 消息本身可以是任何长度,并且异常可以立即发生,有时甚至可以达到完美通信的一分钟 .

我对套接字和网络通信很新,我觉得我可能会遗漏一些东西 . 我已经在至少8台不同的计算机上进行了测试,并且与引发此异常的计算机的唯一相似之处在于它们的操作系统是Windows XP 32位 .

1 回答

  • 1

    你会想要关注the convention shown here . 您正在传递 IAsyncResultSocket.BeginReceive ,它代表上下文中的不同点或完全不同的上下文 .

    确保在回调中使用的是在调用 EndReceive 时传入的参数 .

    Windows XP中可能有一个错误修复程序,具体取决于您的服务包以及您安装的其他内容,它会捕获上下文共享方案,或者可能是因为它引入了一个无法正确管理上下文的错误 . 没有广泛的测试,很难判断它是否是一个环境问题 .

相关问题