In procedure TdwsFileNotifier.Execute, when ReadDirectoryChanges call fails, the thread is terminated by calling Terminate but the loop is not immediately exited. IMO there should be a break immediately after Terminate like this:
FActive:=True;
NameThreadForDebugging('FileNotifier '+AnsiString(FDirectory));
while not Terminated do begin
GetQueuedCompletionStatus(FChangeCP, numBytes, completionKey, FPOverlapped, INFINITE);
if completionKey<>0 then begin
if not ReadDirectoryChanges(FDirectoryHandle, @FNotificationBuffer,
SizeOf(TdwsFileNotifierBuffer),
(FMode=dnoDirectoryAndSubTree), FNotifyFilter,
@FBytesWritten, @FOverlapped, nil) then
Terminate;
fileOpNotification:=@FNotificationBuffer;
repeat
offset:=fileOpNotification^.NextEntryOffset;
if Assigned(FOnFileChanged) then begin
notify:=True;
for i:=0 to High(FIgnoredPaths) do begin
if StrLComp(@fileOpNotification^.FileName[0],
PWideChar(Pointer(FIgnoredPaths[i])),
Length(FIgnoredPaths[i]))=0 then begin
notify:=False;
Break;
end;
end;
if notify then begin
SetString(fileName, fileOpNotification^.FileName,
fileOpNotification^.FileNameLength div SizeOf(Char));
FQueue.QueueNotification(fileName, fileOpNotification^.Action);
end;
end;
fileOpNotification:=@PAnsiChar(fileOpNotification)[offset];
until offset=0;
FBytesWritten:=0;
FillChar(FNotificationBuffer, 0, SizeOf(TdwsFileNotifierBuffer));
end else Terminate;
end;
FActive:=False;