具有I / O完成的asynchronous操作端口返回传输的0个字节

具有I / O完成的asynchronous操作尽pipeI / O操作按预期工作(我的读缓冲区已满),但端口仍返回0字节传输。

BYTE buffer[1024] = {0}; OVERLAPPED o = {0}; HANDLE file = CreateFile( _T("hello.txt"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ); HANDLE completion_port = CreateIoCompletionPort( file, NULL, 0, 0 ); ReadFile( file, buffer, 1024, NULL, &o ); 

在工作线程中:

 DWORD numBytes = 0; LPOVERLAPPED po; GetQueuedCompletionStatus( completion_port, &numBytes, 0, &po, INFINITE ); GetOverlappedResult(file, &o, &numBytes, FALSE); 

这两个函数在numBytes中返回0个字节,但buffer正在填充。 这是预期的行为?

谢谢。

为使GetIoCompletionPort正常工作,您需要指定一个指向ULONG_PTR的非空指针,以便将“key”值写入:

 ULONG_PTR key; GetQueuedCompletionStatus( completion_port, &numBytes, &key, &po, INFINITE ); 

要成功使用GetOverlappedResult ,我相信你需要在OVERLAPPED结构中指定一个事件句柄(强烈建议在任何情况下):

 o.hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); 

像你们一样连续调用这两件事并不是很成功 – 他们都告诉你同样的事情。 虽然如果您连续调用这两个函数,则需要将第三个参数更改为CreateEvent为TRUE,将事件更改为手动重置。 我的猜测是,你只是想看看你能不能找到工作。 所有的事情考虑,我可能只是使用GetQueuedCompletionStatus ,离开它。 当然,你通常不止一次地打电话而退出。 您通常在循环中调用它,处理您读取的当前缓冲区,然后再次调用ReadFile以读取另一个信息缓冲区,如下所示:

 DWORD numBytes; LPOVERLAPPED po; while (GetQueuedCompletionStatus(completion_port, &numBytes, &key, &po, INFINITE)) { std::cout << "\rRead: " << numBytes; // just to show it's set correctly. process(buffer); po->offset += sizeof(buffer); ReadFile(file, buffer, sizeof(buffer), NULL, po); } 

至少在我的机器上进行了一个快速测试,这显示了正确读取的字节数( sizeof(buffer)直到最后一个数据包,然后是文件的剩余大小)。