具有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)
直到最后一个数据包,然后是文件的剩余大小)。