【问题标题】:ReadDirectoryChangesW issuesReadDirectoryChangesW 问题
【发布时间】:2012-10-15 14:21:30
【问题描述】:

我正在使用ReadDirectoryChangesW 异步监视目录更改,基于此question 我实现了一个监视给定目录的函数,但我仍然收到错误消息GetQueuedCompletionStatus(): Timeout

void Filewatcher::OpenWatchDir(QString PathToOpen)
{

    QString path=QDir::fromNativeSeparators(PathToOpen);

    LPCTSTR  Dirname=(LPCTSTR)path.utf16();//.toStdWString().c_str();

    dirinfo_t* d =(dirinfo_t*) malloc(1*sizeof(dirinfo_t));
    d->CompletionKey = (ULONG_PTR)&somekey;
    dirinfo_init(d);

    /* set up */
    runthread = TRUE;
    d->hDirFH = CreateFile(Dirname,
                    FILE_LIST_DIRECTORY,
                    FILE_SHARE_READ|FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
                    NULL);

    d->hDirOPPort = CreateIoCompletionPort(d->hDirFH, NULL,
                          (ULONG_PTR)d->CompletionKey, 1);

    DWORD errorcode = 0;    // an error code
    BOOL bResultQ = FALSE;  // obvios=us
    BOOL bResultR = FALSE;
    DWORD NumBytes = 0;
    FILE_NOTIFY_INFORMATION* pInfo = NULL; // the data incoming is a pointer
                                           // to this struct.
    int i = 0;

    while ( runthread )
        {
            bResultR = ReadDirectoryChangesW(d->hDirFH, (void*)d->buffer,
                                              16777216, TRUE,
                   FILE_NOTIFY_CHANGE_FILE_NAME  | FILE_NOTIFY_CHANGE_CREATION  ,
                                              NULL,
                                              &d->o->overlapped,
                                              NULL );
            bResultQ = GetQueuedCompletionStatus(d->hDirOPPort,
                                                 &NumBytes, &(d->CompletionKey),
                                                 (LPOVERLAPPED*)(d->o), 1000);
            if ( bResultQ && bResultR )
                    {
                wprintf(L"\n");
                pInfo = (FILE_NOTIFY_INFORMATION*) d->buffer;
                wprintf(L"File %s", pInfo->FileName);
                wprintf(L" changes %d\n", pInfo->Action);

                qDebug()<<"file  "<<pInfo->FileName<<" was"<<pInfo->Action;
                memset(d->buffer, 0, 16777216);
            }
            else
                   {
                       errorcode = GetLastError();

                       if ( errorcode == WAIT_TIMEOUT )
                       {
                           qDebug()<<"GetQueuedCompletionStatus(): Timeout\n";
                       }
                       else
                       {
                           qDebug()<<"GetQueuedCompletionStatus(): Failed\n";
                           qDebug()<<"Error Code "<<errorcode;
                       }
                       Sleep(500);
                   }
               }


}

我需要知道如何将ReadDirectoryChangesWIoCompletionPort 异步使用。

请帮忙。

【问题讨论】:

  • 也许在你超时的那一秒内目录没有改变?
  • 我将其更改为 10000 毫秒我现在可以看到我的事件,但我现在的问题是我无法再处理我的应用程序(调用不在单独的线程中),我想这就是异步处理ReadDirectoryChangesW 的重点。如何将我的应用程序线程与监视目录线程分开?
  • oumaya:关键是您可以使用(Msg)WaitForMultipleObjects(Ex)同时等待完成端口和其他对象,甚至是GUI消息。因此,您可以在等待完成端口的同时做其他有用的工作。
  • 嗯,在 Qt 中,您别无选择,只能在单独的线程中运行它。通常,您会将等待集成到您的消息泵中,但不幸的是,Qt 中没有提供此功能。
  • @avakar:所以 Qt 没有等同于 XtAddAppInput 的功能,无法将新的句柄/文件描述符放入等待循环?当它不支持 Win32 和 Unix 工具包几十年来的基本操作时,它是如何获得追随者的?

标签: c++ c winapi asynchronous readdirectorychangesw


【解决方案1】:

这里没有理由使用完成端口,带有事件的简单重叠 I/O 将非常有效。

关键是与所有其他事件(可能包括 GUI 消息)同时等待此操作(无论是事件还是完成端口),并且仅在事件发出信号时检查状态。为此,请使用(Msg)WaitForMultipleObjects(Ex)

在 Qt 中,您可以使用 QWinEventNotifier 添加 Win32 事件(由 OVERLAPPED 结构用于异步 I/O),如下所述:

【讨论】:

  • 请注意,最近几个 Qt 版本中缺少 QWinEventNotifier。见code.google.com/p/qextserialport/issues/detail?id=91
  • @avakar:不,它没有丢失。它只是移动了。在 Qt 5 中,它再次移动,成为公共 API。至少如果那篇博文可以相信的话。
  • 谢谢你们的回答,事实上我正在使用 QT 4.7.4,所以我可以合法地使用QWinEventNotifier 的文章帖子。我将尝试像作者所说的那样继续创建一个新的 QThread 子类,除了在无限循环中调用 Windows WaitForSingleObject() 函数(或 WaitForMultipleObjects() 或任何变体)之外什么都不做。将其设置为阻塞对 Windows 函数的调用,直到发生事件,并在发生任何事情时从线程发出信号。然后你可以将该信号连接到程序中的一个插槽我是新手,那么如何在事件发生之前阻止它?
【解决方案2】:

感谢大家的回答,经过深入研究和重新测试代码后,我根据this 解决了我的问题,非常感谢您的帮助。

【讨论】:

  • 为什么要链接到第三方网站?现在链接失效了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-20
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多