SocketAsyncEventArgs.Completed不会在Windows火8 [英] SocketAsyncEventArgs.Completed doesn't fire in Windows 8
问题描述
当我编译这个code一机Windows 7旗舰版和.NET 4安装,它工作得很好,但是当我尝试在一个与Windows 8 RTM和.NET 4.5安装,完成事件永远不会触发。
When I compile this code on a machine with Windows 7 Ultimate and .NET 4 installed, it works just fine but when I try it on one with Windows 8 RTM and .NET 4.5 installed, Complete event never fires.
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);
}
}
在这里有趣的是,如果我把一个断点在该行并调试它:
The interesting thing here is if I put a breakpoint at this line and debug it:
var arguments = new SocketAsyncEventArgs();
和使用大力神继续执行之前,它的工作原理就像一个魅力。我做这在一开始,然后神奇,OnAccepted被调用,并写道:接受。到每一个连接于控制台。我用的是机器上的相同code和相同的程序(大力神)与Windows 7和.NET 4,但它始终工作。
And connect this server using Hercules before continuing execution, it works like a charm. I do this at the start and then magically, OnAccepted gets called and writes "Accepted." to the console on every single connection. I use the same code and same program (Hercules) on the machine with Windows 7 and .NET 4 but it always works.
- 我是不是做错了什么?
- 如果不是,它是我的操作系统或.NET Framework版本4.5的一个已知的bug?
- 在任何人都可以复制吗?
修改:这两个操作系统的64位
修改2 :我报这是在Microsoft Connect上的错误,<一个href="https://connect.microsoft.com/VisualStudio/feedback/details/759913/socketasynceventargs-completed-doesnt-fire-in-net-framework-4-5"相对=nofollow称号=SocketAsyncEventArgs.Completed不火的.NET框架4.5>此处。
修改3 :找到一个解决办法,并张贴到Connect(只需创建一个假的,第一个连接)
。
修改4 :如果任何人都可以重现此,请在连接投身问题
修改5 :我看到托马斯已经提到的问题,我测试是否到Console.ReadLine
是造成这一与否。原来它是。如果我添加 Thread.sleep代码(3000)
我到Console.ReadLine
电话之前,使在3秒的连接尝试我运行程序后,它的工作原理就像一个魅力。同样,奇怪的是,我需要调用到Console.ReadLine
之前,要做到这一点只有一次。如果我让调用到Console.ReadLine
前一个连接,然后每一个连续的连接工作,即使在到Console.ReadLine
被调用。我将在瞬移页提到这一点。
修改6 :我加入了另外一个问题的链接,连接页面,并增加了一个解决方法,需要调用 Thread.sleep代码
之前调用到Console.ReadLine
就像我在上面提到的修改
Edit: Both operating systems are 64 bit.
Edit 2: I reported this as a bug on Microsoft Connect, here.
Edit 3: Found a workaround and post it to Connect (Simply by creating a fake, first connection).
Edit 4: If anyone can reproduce this, please join the issue in Connect.
Edit 5: I saw the question Thomas has mentioned and I tested whether Console.ReadLine
was causing this or not. Turned out it was. If I add Thread.Sleep(3000)
before my Console.ReadLine
call and make a connection attempt in 3 seconds after I run the program, it works like a charm. Again, the odd thing is that I need to do this only once before calling Console.ReadLine
. If I make one connection before calling Console.ReadLine
then every consecutive connection works, even after Console.ReadLine
is called. I'll mention this in the Conect page.
Edit 6: I added the link to the other question to the Connect page and added another workaround that involves calling Thread.Sleep
before calling Console.ReadLine
like I mentioned in the above edit.
推荐答案
这竟然是一个Windows 8的错误。最好的解决方法,我能找到到目前为止是开始在不同的线程的IOCP操作。
It turned out to be a Windows 8 bug. Best workaround I could find so far is to start the IOCP operation on a different thread.
所以,事情我应该做的就是给出问题的code样品中改变这一行:
So the thing I should do in the code sample that is given in the question is changing this line:
Accept(arguments);
要此行的主
方法:
Task.Run(() => Accept(arguments)).Wait();
这prevents 到Console.ReadLine()
来电阻止IOCP操作。
This prevents Console.ReadLine()
call to block the IOCP operation.
的作为一个方面说明:这只是一种变通方法,以一个操作系统漏洞,这将最有可能通过更新和-hopefully-使此解决办法多余的固定的
此问题已修复与Windows 8的最新版本。
This issue is fixed with the latest version of Windows 8.
编辑:的反馈项目状态我已经张贴在连接更改为按设计。
我也收到一封电子邮件,其中包含以下内容:
Status of the feedback item I have posted in Connect is changed to "By Design".
I also received an e-mail which contains the following:
有关这种现象的根本问题与办怎么IO 完成端口在Windows处理8 .NET工程使用 完成端口;当他们的行为改变了,所以做了.NET 行为。
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:反馈的状态再次更改为主动,没有细节
Edit 2: Status of the feedback is changed again to "Active" with no details.
修改3:反馈收到了微软另一个答案,他表示:
Edit 3: The feedback received another answer from Microsoft, stating:
Windows 8的最新版本应该有这个固定的。请注意,这是一个操作系统问题,而不是.NET的问题:你需要确保你的操作系统的最新版本。未进行任何更改到.NET要么原因或解决此问题。
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."
这篇关于SocketAsyncEventArgs.Completed不会在Windows火8的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!