I / O完成端口的异步操作返回0字节传输,尽管I / O操作按预期工作(我的读缓冲区已满)。
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
正在填充。这是预期的行为吗?
感谢。
答案 0 :(得分:3)
要使GetIoCompletionPort
正常工作,您需要指定一个指向ULONG_PTR
的非空指针,以便将'key'值写入:
ULONG_PTR key;
GetQueuedCompletionStatus(
completion_port,
&numBytes,
&key,
&po,
INFINITE
);
要成功使用GetOverlappedResult
,我相信您需要在OVERLAPPED
结构中指定事件句柄(强烈建议在任何情况下使用):
o.hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
像你一样连续打电话给两人并没有太大的成就 - 他们都告诉你同样的事情。虽然如果你连续两次调用,你需要通过将第三个参数更改为CreateEvent
来将事件更改为手动重置。我的猜测是,你只是想两个人,看看你是否可以让一个人上班。考虑到所有事情,我可能只是使用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)
直到最后一个数据包,然后是文件的剩余大小。)