1

1 つのスレッドで複数のディレクトリの変更をリアルタイムで監視したいので、GetQueuedCompletionStatus と非同期で ReadDirectoryChangesW() メソッドを使用することにしました。これが私のコードです:

static DWORD WINAPI Routine( LPVOID lParam )
{
    FileSystemWatcher* obj = (FileSystemWatcher*)lParam;

    obj->hDir[0] = CreateFile(
        obj->WatchedDir[0].c_str(),
        GENERIC_READ|GENERIC_WRITE,
        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,
        NULL
    );

    obj->hDir[1] = CreateFile(
   obj->WatchedDir[1].c_str(),
   GENERIC_READ|GENERIC_WRITE,
   FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
   NULL,
   OPEN_EXISTING,
   FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,
   NULL
    );

    if( INVALID_HANDLE_VALUE == obj->hDir[0] || INVALID_HANDLE_VALUE == obj->hDir     [1] ) 
{
    return false;
}

obj->IOCPHandle[0] = CreateIoCompletionPort(obj->hDir[0], NULL, 0, 1);
obj->IOCPHandle[1] = CreateIoCompletionPort(obj->hDir[1], NULL, 0, 1);

if (obj->IOCPHandle[0] == INVALID_HANDLE_VALUE || obj->IOCPHandle[1] ==  INVALID_HANDLE_VALUE)
{
    return false;
}

    char buf[ 2*(sizeof(FILE_NOTIFY_INFORMATION)+MAX_PATH) ];
    FILE_NOTIFY_INFORMATION* pNotify=(FILE_NOTIFY_INFORMATION *)buf;
    DWORD BytesReturned;
    LPOVERLAPPED overLap = NULL;

    m_pFileNotifyInfo = pNotify;
    dirEvents[0] = CreateEvent(NULL, TRUE, FALSE, NULL);
    dirEvents[1] = CreateEvent(NULL, TRUE, FALSE, NULL);*/

    while(true)
    {

    BOOL success = ReadDirectoryChangesW( obj->hDir[0],
    pNotify,
    sizeof(buf),
    true,
    FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME,
    &BytesReturned,
    overLap,
    NULL );
    BOOL success1 = ReadDirectoryChangesW( obj->hDir[1],
    pNotify,
    sizeof(buf),
    true,
    FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME,
    &BytesReturned,
    overLap,    
                 NULL );

    LPOVERLAPPED theOverLap;
    PULONG_PTR lpCompKey = NULL;
    if (GetQueuedCompletionStatus(obj->IOCPHandle[0], &BytesReturned, lpCompKey, &overLap, 100))
    {
    cout<<"First Dir Changed"<<endl;
    }

    if (GetQueuedCompletionStatus(obj->IOCPHandle[1], &BytesReturned, lpCompKey, &overLap, 100))
    {
    cout<<"Second Dir Changed"<<endl;
    }

    cout<<"Nothing happened yet"<<endl;

       }

    return 0;
}

ここでコードを実行すると、GetQueuedCompletionStatus() 関数の最後のパラメーターに設定した値に関係なく、理由もなくスレッドがブロックされます。なぜこの問題に遭遇したのかわかりません。誰でも理由を教えてもらえますか? どうもありがとう!

4

1 に答える 1

1
  1. 非同期 I/O が機能するには、有効な OVERLAPPED 構造を指定する必要があります。NULL ( LPOVERLAPPED overLap = NULL;) を使用しています。

  2. 同時 I/O 操作では、1 つだけでなく、個別の OVERLAPPED 構造を使用する必要があります。

  3. 本当にIOCPが必要ですか?OVERLAPPEDhEvent構造に入力してWaitForMultipleObjects、これらのイベントを実行します。

于 2008-12-08T17:40:14.073 に答える