2008-12-05 9 views
1

Je souhaite surveiller en temps réel les modifications de plusieurs répertoires dans un thread, j'ai donc décidé d'utiliser la méthode ReadDirectoryChangesW() de manière asynchrone avec GetQueuedCompletionStatus. Voici mon code:Blocage de thread lors de l'utilisation de ReadDirectoryChangesW de manière asynchrone

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; 
} 

ici quand je lance mon code, mes blocs de fil pour aucune raison, quelle que soit la valeur que je mets au dernier paramètre de la fonction GetQueuedCompletionStatus(). Je ne sais pas pourquoi j'ai rencontré ce problème. Quelqu'un peut-il dire à ma raison? Merci beaucoup!

Répondre

1
  1. Vous devez spécifier une structure OVERLAPPED valide pour que les E/S asynchrones fonctionnent. Vous utilisez NULL (LPOVERLAPPED overLap = NULL;).

  2. opérations simultanées d'E/S doivent utiliser des structures OVERLAPPED séparées, pas seulement un.

  3. Êtes-vous sûr que vous avez besoin IOCP du tout? Je voudrais juste remplir hEvent dans les structures et faire un OVERLAPPED WaitForMultipleObjects sur ces événements.

Questions connexes