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