加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

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

发布时间:2020-12-14 05:41:19 所属栏目:Windows 来源:网络整理
导读:当我在安装了 Windows 7 Ultimate和.NET 4的机器上编译此代码时,它工作得很好但是当我在安装了Windows 8 RTM和.NET 4.5的机器上进行尝试时,Complete事件永远不会触发. class Program{ private static Socket _Socket = new Socket( AddressFamily.InterNetwo
当我在安装了 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被调用并写入“已接受”.每个连接上的控制台.我在使用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是否导致了这个问题.原来是.如果我在Console.ReadLine调用之前添加Thread.Sleep(3000)并在运行程序后3秒内进行连接尝试,它就像魅力一样.同样,奇怪的是我在调用Console.ReadLine之前只需执行一次.如果在调用Console.ReadLine之前建立一个连接,则每个连续的连接都会起作用,即使在调用Console.ReadLine之后也是如此.我将在Conect页面中提到这一点.
编辑6:我将另一个问题的链接添加到Connect页面,并添加了另一个解决方法,涉及在调用Console.ReadLine之前调用Thread.Sleep,就像我在上面的编辑中提到的那样.

解决方法

原来这是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.”

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读