4

当我在安装了 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 上的错误。
编辑 3:找到一种解决方法并将其发布到 Connect(只需创建一个虚假的第一个连接)。
编辑 4:如果有人可以重现此问题,请加入 Connect 中的问题。
编辑 5:我看到了Thomas 提到的问题,我测试了是否Console.ReadLine导致了这个问题。原来是这样。如果我在通话前添加并Thread.Sleep(3000) Console.ReadLine运行程序后 3 秒内尝试连接,它就像一个魅力。同样,奇怪的是我只需要在调用Console.ReadLine. 如果我在打电话之前建立一个连接Console.ReadLine然后每个连续的连接都有效,即使在Console.ReadLine被调用之后也是如此。我将在连接页面中提到这一点。
编辑6:我将另一个问题的链接添加到连接页面,并添加了另一个解决方法,涉及在调用Thread.Sleep之前调用,Console.ReadLine就像我在上面的编辑中提到的那样。

4

1 回答 1

1

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

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

Accept(arguments);

Main方法中的这一行:

Task.Run(() => Accept(arguments)).Wait();

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

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

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


编辑:我在 Connect 中发布的反馈项目的状态更改为“按设计”。
我还收到一封电子邮件,其中包含以下内容:

此行为的根本问题与 Windows 8 中如何处理 IO 完成端口有关。.NET 使用完成端口工作;当他们的行为发生变化时,.NET 行为也发生了变化。

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

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

最新版本的 Windows 8 应该已修复此问题。请注意,这是操作系统问题,而不是 .NET 问题:您需要确保拥有最新版本的操作系统。没有对 .NET 进行任何更改来导致或解决此问题。”

于 2012-11-09T13:55:20.367 回答