2009-10-21 41 views
2

带I/O完成的异步操作虽然I/O操作按预期工作(我的读取缓冲区已满),但端口仍返回传输0字节。具有I/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被填充。这是预期的行为?

谢谢。

回答

3

GetIoCompletionPort正常工作,你需要指定一个非空指针ULONG_PTR为它写了“关键”值:

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

+0

是的,你是正确的关键指针。你也假设我尝试了这两个函数来判断它们是否有效:-)。 谢谢。 – 2009-10-22 13:21:01