【问题标题】:C# TCP Async EndReceive() throws InvalidOperationException ONLY on Windows XP 32-bitC# TCP Async EndReceive() 仅在 Windows XP 32 位上抛出 InvalidOperationException
【发布时间】:2013-11-08 05:51:56
【问题描述】:

我有一个简单的 C# 异步客户端,它使用 .NET 套接字等待来自本地 Java 服务器的定时消息,用于自动执行命令。消息异步传入并写入环形缓冲区。此实现似乎在 Windows Vista/7/8 和 OSX 上运行良好,但在接收来自本地 Java 服务器的消息时会随机抛出此异常:

未处理的异常:System.InvalidOperationException:每个异步操作只能调用一次 EndReceive。
在 System.Net.Sockets.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 位。

【问题讨论】:

    标签: c# .net sockets asynchronous


    【解决方案1】:

    你会想要关注the convention shown here。您将IAsyncResult 传递给Socket.BeginReceive,它代表上下文中的不同点或完全不同的上下文。

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

    Windows XP 中可能有一个错误修复,这取决于您的服务包和您安装的其他东西,它捕获了上下文共享场景,或者它可能引入了一个错误,它不能正确管理上下文。如果没有大量测试,很难判断这是否是环境问题。

    【讨论】:

    • 刚刚测试过,现在似乎可以正常工作了,谢谢!奇怪的是,它只发生在 WinXP 上,如果我发现更多,我会回复。
    • @JamesFarmer 我在 Windows XP 开发盒上进行了测试,但无法通过最新更新重现该问题。这告诉我它可能是旧版本框架中的错误或类似的东西。
    猜你喜欢
    • 2014-10-14
    • 2019-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多