.net - SocketAsyncEventArgs.Completed 在 Windows 8 中不会触发

标签 .net windows-8 asyncsocket iocp

当我在安装了 Windows 7 Ultimate 和 .NET 4 的机器上编译此代码时,它工作得很好,但是当我在安装了 Windows 8 RTM 和 .NET 4.5 的机器上尝试它时,Complete 事件永远不会触发。

class Program
{
    private static Socket _Socket = new Socket(
        AddressFamily.InterNetwork,
        SocketType.Stream,
        ProtocolType.Tcp);

    private static void Main(string[] args)
    {
        _Socket.Bind(new IPEndPoint(IPAddress.Any, 5012));
        _Socket.Listen(100);

        var arguments = new SocketAsyncEventArgs();
        arguments.Completed += OnAccepted;
        Accept(arguments);

        Console.ReadLine();
    }

    private static void Accept(SocketAsyncEventArgs args)
    {
        args.AcceptSocket = null;
        if (!_Socket.AcceptAsync(args))
            OnAccepted(null, args);
    }

    private static void OnAccepted(object sender, SocketAsyncEventArgs e)
    {
        Console.WriteLine("Accepted.");
        Accept(e);
    }
}

有趣的是,如果我在这一行设置断点并对其进行调试:
var arguments = new SocketAsyncEventArgs();

并使用 Hercules 连接此服务器在继续执行之前,它就像一个魅力。我一开始就这样做,然后神奇地调用 OnAccepted 并写入“Accepted”。在每个连接上到控制台。我在装有 Windows 7 和 .NET 4 的机器上使用相同的代码和相同的程序 (Hercules),但它始终有效。
  • 难道我做错了什么?
  • 如果不是,它是我的操作系统或 .NET Framework 4.5 版的已知错误吗?
  • 任何人都可以重现这个吗?

  • 编辑 : 两个操作系统都是 64 位的。
    编辑 2 :我将此作为 Microsoft Connect 上的错误报告,here .
    编辑 3 :找到一种解决方法并将其发布到 Connect(只需创建一个虚假的第一个连接)。
    编辑 4 : 如果有人可以复制这个,请加入 Connect 中的问题。
    编辑 5 : 我看到了question Thomas has mentioned我测试了 Console.ReadLine是不是造成了这个。原来是这样。如果我添加 Thread.Sleep(3000) 之前 我的 Console.ReadLine在我运行程序后 3 秒内调用并尝试连接,它就像一个魅力。同样,奇怪的是在调用 Console.ReadLine 之前我只需要这样做一次。 .如果我在调用 Console.ReadLine 之前建立一个连接然后每个连续的连接都有效,即使在 Console.ReadLine 之后叫做。我将在连接页面中提到这一点。
    编辑 6 :我将另一个问题的链接添加到连接页面,并添加了另一个解决方法,涉及调用 Thread.Sleep在调用 Console.ReadLine 之前就像我在上面的编辑中提到的那样。

    最佳答案

    事实证明这是一个 Windows 8 错误。到目前为止,我能找到的最佳解决方法是在不同的线程上启动 IOCP 操作。

    所以我应该在问题中给出的代码示例中做的事情是改变这一行:

    Accept(arguments);
    

    Main 中的这一行方法:
    Task.Run(() => Accept(arguments)).Wait();
    

    这可以防止 Console.ReadLine()调用以阻止 IOCP 操作。

    附带说明:这只是操作系统错误的一种解决方法,很可能通过更新来修复,并且 - 希望 - 使这种解决方法变得多余。

    此问题已在最新版本的 Windows 8 中得到修复。

    编辑: feedback item I have posted in Connect 的状态更改为“按设计”。
    我还收到一封电子邮件,其中包含以下内容:

    The underlying issue for this behavior has to do with how IO Completion Ports are handled in Windows 8. .NET works using the completion ports; when their behavior changed, so did the .NET behavior.



    编辑 2:反馈的状态再次更改为“事件”,没有详细信息。

    编辑 3:反馈收到了微软的另一个答复,指出:

    The latest version of Windows 8 should have this fixed. Note that it's an OS issue, not a .NET issue: you need to make sure you have the latest version of the OS. No changes were made to .NET to either cause or fix this issue."

    关于.net - SocketAsyncEventArgs.Completed 在 Windows 8 中不会触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12145378/

    相关文章:

    c# - 什么是 [Serializable] 以及我应该何时使用它?

    c# - HttpClient 究竟是如何处理超时的?

    visual-studio - 在 Windows 8 上运行 Visual Studio 2008

    sockets - Python3 : Socket Receive gets all data at the same time

    c - recvmsg linux 接收到错误的数据

    .net - 这个 OleDBCommand 有什么问题?

    .net - 验证签名的 Word 文档的正确方法是什么?

    c# - Windows 8.1 应用程序是否可以在 Windows 8 PC 上运行?

    windows - 为什么 Windows Shell 上下文菜单处理程序会破坏 Windows 8/10 上的高级用户菜单 (Win+x)?

    c++ - 在调用前一个完成处理程序之前异步发送数据是否有效?