Winapi 异步ReadDirectoryChangesW失败,错误为\u参数无效

Winapi 异步ReadDirectoryChangesW失败,错误为\u参数无效,winapi,asynchronous,Winapi,Asynchronous,我已经设法同步使用了ReadDirectoryChangesW,但是当我尝试使用完成端口时,ReadDirectoryChangesW总是返回错误\u无效\u参数。我想我的代码中应该有一些明显的错误,但我无法理解 我的代码是基于 正如Hans Passant善意地提醒的那样,他已经说过,如果目录与完成端口关联,则不能使用完成例程。在本例中,我通过等待完成端口解决了问题,即,ReadDirectoryChangesW(…,&overlapped,0) 完整的代码如下 while (true) {

我已经设法同步使用了
ReadDirectoryChangesW
,但是当我尝试使用完成端口时,
ReadDirectoryChangesW
总是返回
错误\u无效\u参数
。我想我的代码中应该有一些明显的错误,但我无法理解

我的代码是基于


正如Hans Passant善意地提醒的那样,他已经说过,如果目录与完成端口关联,则不能使用完成例程。在本例中,我通过等待完成端口解决了问题,即,
ReadDirectoryChangesW(…,&overlapped,0)

完整的代码如下

while (true) {
    OVERLAPPED overlapped;
    memset(&overlapped,0,sizeof(overlapped));
    BOOL success = ReadDirectoryChangesW(h,
            &buffer[0],
            4096*sizeof(DWORD),
            FALSE, notifyFilter, 0, &overlapped,0);

    if (!success) {
      if (GetLastError()==ERROR_INVALID_HANDLE) {
        //asynchronously closed by cancel
        CloseHandle(p); //close completion port
        return 0;
      } else {
        CloseHandle(h); //close directory handle
        CloseHandle(p); //close completion port
        return 1;
      }
    }

    DWORD di;
    LPOVERLAPPED lpOverlapped;
    if (!GetQueuedCompletionStatus(p,&bytesReturned,&di,&lpOverlapped,1000)) {
        int ret;
        if (GetLastError()==WAIT_TIMEOUT) {
            if (GetFileAttributes(directory)!=INVALID_FILE_ATTRIBUTES) {
                continue; //timeout
            } else {
                //directory has been deleted or renamed
                ret=0;
            }
        } else {
            //other failure
            ret=1;
        }
        CloseHandle(h); //close directory handle
        CloseHandle(p); //close completion port
        return ret;
    }

    char* ptr = (char*)&buffer[0];
    char* end = ptr+bytesReturned;
    while (ptr<end) {
      FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION*) ptr;
      //process FILE_NOTIFY_INFORMATION
      ptr+=info->NextEntryOffset;
      if (!info->NextEntryOffset) break;
    }
  }
while(true){
重叠;
memset(&overlapped,0,sizeof(overlapped));
BOOL success=ReadDirectoryChangesW(h,
&缓冲区[0],
4096*sizeof(德沃德),
FALSE,notifyFilter,0,重叠(&O),0);
如果(!成功){
if(GetLastError()==错误\u无效\u句柄){
//通过取消异步关闭
CloseHandle(p);//关闭完成端口
返回0;
}否则{
CloseHandle(h);//关闭目录句柄
CloseHandle(p);//关闭完成端口
返回1;
}
}
德沃德·迪;
lp重叠lp重叠;
如果(!GetQueuedCompletionStatus(p,&bytesReturned,&di,&lpOverlapped,1000)){
int ret;
如果(GetLastError()==等待\u超时){
如果(GetFileAttributes(目录)!=无效的文件属性){
继续;//超时
}否则{
//目录已被删除或重命名
ret=0;
}
}否则{
//其他故障
ret=1;
}
CloseHandle(h);//关闭目录句柄
CloseHandle(p);//关闭完成端口
返回ret;
}
char*ptr=(char*)和缓冲区[0];
char*end=ptr+bytes返回;
while(ptrNextEntryOffset;
如果(!info->nexteryOffset)中断;
}
}

您没有显示notifyFilter和myFileIOCompletionRoutine定义。CreateIoCompletionPort返回NULL如果失败,则测试不正确。可能CreateIoCompletionPort失败?@AlexFarber,谢谢您指出,但CreateIoCompletionPort返回有效句柄。@AlexFarber我添加了notifyFilter.myFileIOCompletionRout的声明ine目前什么都不做,即MSDN库文章中的重要说明:
要通过完成例程接收通知,请**不要**将目录与完成端口关联。
如果您帮助很大,请删除CreateIoCompletionPort()调用。
while (true) {
    OVERLAPPED overlapped;
    memset(&overlapped,0,sizeof(overlapped));
    BOOL success = ReadDirectoryChangesW(h,
            &buffer[0],
            4096*sizeof(DWORD),
            FALSE, notifyFilter, 0, &overlapped,0);

    if (!success) {
      if (GetLastError()==ERROR_INVALID_HANDLE) {
        //asynchronously closed by cancel
        CloseHandle(p); //close completion port
        return 0;
      } else {
        CloseHandle(h); //close directory handle
        CloseHandle(p); //close completion port
        return 1;
      }
    }

    DWORD di;
    LPOVERLAPPED lpOverlapped;
    if (!GetQueuedCompletionStatus(p,&bytesReturned,&di,&lpOverlapped,1000)) {
        int ret;
        if (GetLastError()==WAIT_TIMEOUT) {
            if (GetFileAttributes(directory)!=INVALID_FILE_ATTRIBUTES) {
                continue; //timeout
            } else {
                //directory has been deleted or renamed
                ret=0;
            }
        } else {
            //other failure
            ret=1;
        }
        CloseHandle(h); //close directory handle
        CloseHandle(p); //close completion port
        return ret;
    }

    char* ptr = (char*)&buffer[0];
    char* end = ptr+bytesReturned;
    while (ptr<end) {
      FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION*) ptr;
      //process FILE_NOTIFY_INFORMATION
      ptr+=info->NextEntryOffset;
      if (!info->NextEntryOffset) break;
    }
  }