C# IOCP GetQueuedCompletionStatus返回空lpOverlapped

C# IOCP GetQueuedCompletionStatus返回空lpOverlapped,c#,iocp,C#,Iocp,我正在尝试使用从kernel32.dll和ws2_32.dll导入的Win32API用C编写IOCP服务器 该问题发生在工作线程中。如果我经常向服务器发出请求,它会在10秒内消失。打破循环!具体情况是,GetQueuedCompletionStatus函数返回false后,返回的整数指针lpOverlapped为NULL,GetLastWin32Error返回代码735,即错误\u放弃\u等待\u 0 该错误在msdn中描述如下: 如果对GetQueuedCompletionStatus的调用失

我正在尝试使用从kernel32.dll和ws2_32.dll导入的Win32API用C编写IOCP服务器

该问题发生在工作线程中。如果我经常向服务器发出请求,它会在10秒内消失。打破循环!具体情况是,GetQueuedCompletionStatus函数返回false后,返回的整数指针lpOverlapped为NULL,GetLastWin32Error返回代码735,即错误\u放弃\u等待\u 0

该错误在msdn中描述如下:

如果对GetQueuedCompletionStatus的调用失败,因为在调用未完成时与其关联的完成端口句柄已关闭,则函数返回FALSE,*lpOverlapped将为NULL,GetLastError将返回错误\u放弃\u等待\u 0

但当我调试该程序时,completionPort变量是有效的,并且似乎没有关闭完成端口。请看一下代码

public int WorkerThread()
{       
    ...
    while (true) {
        // Wait until all socket I/O completes.
        bool ret = GetQueuedCompletionStatus(
            completionPort: completionPort,
            lpNumberOfBytesTransferred: out bytesTransferred,
            lpCompletionKey: out intPtrPerHandleData,
            lpOverlapped: out intPtrOverlapped,
            dwMilliseconds: uint.MaxValue);

        // WHAT IS WRONG!?!??!
        if (intPtrOverlapped == IntPtr.Zero)
        {
            Logger.ErrorLog();
            break;
        }

        // Recover PerIoData and PerHandleData from IntPtr
        ...

        // Disconnected from client.
        if (ret == false && bytesTransferred == 0) {
            socketRefCount[perHandleData.Socket]--;
            if (socketRefCount[perHandleData.Socket] == 0)
            {
                socketRefCount.Remove(perHandleData.Socket);
                perHandleData.Socket.Close();
            }
            gchPerHandleData.Free();
            gchPerIoData.Free();
        }
    }
}
我认为完成端口是可以的,所以我首先更改了break子句以继续。然后,它首先使735错误被放弃,然后无限地使错误代码6 WSA无效。下面是简化的日志

Thread[4] : Error[735]
Thread[5] : Error[735]
Thread[7] : Error[735]
Thread[6] : Error[735]
Thread[4] : Error[6]
Thread[5] : Error[6]
Thread[7] : Error[6]
Thread[6] : Error[6]
Thread[4] : Error[6]
Thread[5] : Error[6]
...
所以完成端口有问题,对吗?你能解释一下我遇到的问题是什么以及导致这个问题的可能原因吗?我只是每秒发送10到20个50字节的消息。我认为这是很少的,但服务器甚至一分钟也负担不起!每次发生此错误时,是否必须重建I/O完成端口和工作线程?i、 重置服务器

--更新!
添加了工作线程代码的完整版本:

您必须首先测试ret变量。谢谢@HansPassant,但如果完成端口本身有问题,则首先测试ret似乎不会改变结果……您的代码已损坏。修复您的代码,然后更新您的问题。@HansPassant我添加了代码链接!这就足够认识到问题了吗?我甚至懒得去看这个问题,因为你整个事情都做错了。如果要将IOCP与网络套接字一起使用,请使用System.Net.Sockets.socket类的异步API。它在下面使用IOCP。