Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.08.03;
Скачать: CL | DM;

Вниз

завершение ReadDirectoryChanges   Найти похожие ветки 

 
Yury   (2008-06-30 15:51) [0]

Есть программа, кот. просматривает каталоги на предмет появления файлов. Использую для этого ReadDirectoryChanges. это дело запускается в отдельном thread. Так вот как корректно остановить thread, ведь дойдя до ReadDirectoryChanges thread "висит" пока в каталоге что-то не измениться...


 
clickmaker ©   (2008-06-30 15:53) [1]

так ее ж можно асинхронно выполнять


 
Игорь Шевченко ©   (2008-06-30 15:54) [2]


> Так вот как корректно остановить thread


запускать ReadDirectoryChangesW в асинхронном режиме. Создать дополнительный объект "Событие". Ждать с помощью функции WaitForMultipleEvents на обоих событиях - созданном и событии из структуры Overlapped для ReadDirectoryChangesW.


 
Yury   (2008-06-30 15:57) [3]


> запускать ReadDirectoryChangesW в асинхронном режиме. Создать
> дополнительный объект "Событие". Ждать с помощью функции
> WaitForMultipleEvents на обоих событиях - созданном и событии
> из структуры Overlapped для ReadDirectoryChangesW.

а подробнее, если можно с примером...


 
Игорь Шевченко ©   (2008-06-30 16:46) [4]


> а подробнее, если можно с примером...

constructor TMonitorThread.Create(AStopEvent, ADirectoryHandle: THandle);
begin
 inherited Create(true);
 FEventsToWait[0] := AStopEvent;
 FEventsToWait[1] := CreateEvent(nil, true, false, nil);
 FOverlapped.hEvent := FEventsToWait[1];
 FDirectoryHandle := ADirectoryHandle;
 FBuffer := AllocMem(FOLDER_MONITOR_BUFFER_SIZE);
 if not Assigned(FBuffer) then
   SetEvent(AStopEvent);
end;

procedure TMonitorThread.Execute;
var
 BytesRead: DWORD;
 WaitResult: DWORD;
 Files: TStringList;
 I: Integer;
begin
 if WaitForSingleObject(FEventsToWait[0], 1) <> WAIT_TIMEOUT then
   Exit;
 while not Terminated do begin
   if not ReadDirectoryChangesW (FDirectoryHandle, FBuffer,
       FOLDER_MONITOR_BUFFER_SIZE, false, FILE_NOTIFY_CHANGE_FILE_NAME,
       @BytesRead, @FOverlapped, nil) then begin
     OnError(SysErrorMessage(GetLastError));
     Terminate;
     Break; //Невозможно поставить запрос наблюдения каталога в очередь
   end;
   WaitResult := WaitForMultipleObjects(2, @FEventsToWait, false, INFINITE);
   if WaitResult = WAIT_OBJECT_0 then begin
     Terminate;
     Break; //Получен внешний запрос на окончание наблюдения
   end else if WaitResult <> WAIT_OBJECT_0+1 then begin
     OnError(SysErrorMessage(GetLastError));
     Terminate;
     Break; //Неизвестная ошибка
   end else begin
     //Закончилась операция чтения изменений в каталоге
     if not GetOverlappedResult (FDirectoryHandle, FOverlapped, BytesRead,
         false) then begin
       OnError(SysErrorMessage(GetLastError));
       Terminate;
       Break; //Неизвестная ошибка при попытке получения результата окончания
              //асинхронной операции ввода-вывода
     end;
     // Сейчас в буфере находится BytesRead байт информации об изменениях в
     // каталоге
.................................
   end;
 end;
end;


 
Yury   (2008-06-30 18:16) [5]

я не особо в этом силен...
что за тип  FEventsToWait ?


 
Yury   (2008-06-30 18:18) [6]

и FOverlapped


 
Ляпа   (2008-06-30 18:20) [7]


> Yury   (30.06.08 18:16) [5]
> я не особо в этом силен...
> что за тип  FEventsToWait ?


FEventsToWait[1] := CreateEvent.........
F1:
HANDLE CreateEvent(
   LPSECURITY_ATTRIBUTES lpEventAttributes, // pointer to security attributes  
   BOOL bManualReset, // flag for manual-reset event
   BOOL bInitialState, // flag for initial state
   LPCTSTR lpName  // pointer to event-object name  
  );

Ку?


 
Yury   (2008-06-30 18:24) [8]

при компиляции делфи ругается на FEventsToWait. пишет undeclared identifer.


 
Ляпа   (2008-06-30 18:34) [9]


> Yury   (30.06.08 18:24) [8]
> при компиляции делфи ругается на FEventsToWait. пишет undeclared
> identifer.

Так объяви,в чём проблема?
FEventsToWait:array[0..1] of THandle;


 
Leonid Troyanovsky ©   (2008-06-30 18:34) [10]


> Yury   (30.06.08 18:16) [5]

> я не особо в этом силен...

Это хуже чем у Островского!
Если хотите играть подобные сцены - идите в Малый,
и бегайте там по Малому.

Никогда вам не ходить по Большому!

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2008-06-30 18:46) [11]


> Yury   (30.06.08 15:51)  

> Есть программа, кот. просматривает каталоги на предмет появления
> файлов. Использую для этого ReadDirectoryChanges. это дело
> запускается в отдельном thread. Так вот как корректно остановить
> thread, ведь дойдя до ReadDirectoryChanges thread "висит"
> пока в каталоге что-то не измениться

А зачем RDCW, если речь лишь о появлении?
FindFirstChangeNotification with FindFirst &etc.

Прервать же любой *WaitFor*Ex можно простым QueueUserAPC.

--
Regards, LVT.


 
Ляпа   (2008-06-30 18:49) [12]


> Yury   (30.06.08 18:24) [8]

Не дожидаясь дальнейших "ругательств"...
Что-то типа этого:

type
 TOnErrorEvent = procedure(Errmsg: string) of object;
const
FOLDER_MONITOR_BUFFER_SIZE=.....;
type TMonitorThread=class(TThread)
private
   FEventsToWait:array[0..1] of THandle;
   FOverlapped:TOverlapped;
   FDirectoryHandle:THandle;
   FBuffer:PByte;
   OnError:TOnErrorEvent;
protected
   procedure Execute;override;
public
   Constructor Create(AStopEvent, ADirectoryHandle: THandle);
end;


 
Leonid Troyanovsky ©   (2008-06-30 18:53) [13]


> Ляпа   (30.06.08 18:49) [12]

> Не дожидаясь дальнейших "ругательств"...

А деструктор? ;)

--
Regards, LVT.


 
Ляпа   (2008-06-30 18:58) [14]


> Leonid Troyanovsky ©   (30.06.08 18:53) [13]

Может, ему еще и Execute дописать? -)


 
Leonid Troyanovsky ©   (2008-06-30 19:04) [15]


> Ляпа   (30.06.08 18:58) [14]

> Может, ему еще и Execute дописать? -)

А то. Он же и в этом, видимо, не силен.
Ослабли, т.е., мыслительные мышцы.

--
Regards, LVT.


 
Сергей М. ©   (2008-06-30 21:10) [16]


> Leonid Troyanovsky ©   (30.06.08 18:46) [11]
>
> Прервать же любой *WaitFor*Ex можно простым QueueUserAPC.


А за каким вообще лешим нужен асинхронный режим RDCW с последующим абортом в виде QueueUserAPC, если синхронное исполнение RDCW можно корректно прервать закрыв из другого потока хэндл hDirectory ?

Или не можно ?
Не проверял, но подозреваю, что в случае с RDCW ситуация в этом плане лучше чем в случае с пайповыми синхронными вызовами Read/WriteFile ...


 
Игорь Шевченко ©   (2008-06-30 21:54) [17]


> я не особо в этом силен...


За остальное надо платить денег


 
Leonid Troyanovsky ©   (2008-07-01 11:31) [18]


> Сергей М. ©   (30.06.08 21:10) [16]

> Или не можно ?

Я тоже не проверял :)
Оставим заинтересованным лицам.

--
Regards, LVT.



Страницы: 1 вся ветка

Текущий архив: 2008.08.03;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.024 c
15-1213603995
TUser
2008-06-16 12:13
2008.08.03
Что делать с Raid-дисками?


2-1214643313
Дядя Педро
2008-06-28 12:55
2008.08.03
WinAMP


15-1213659824
Randew
2008-06-17 03:43
2008.08.03
Подскажите литературу


2-1214983297
Олег-5
2008-07-02 11:21
2008.08.03
TListBox + пустое есто


15-1213760616
AlexanderMS
2008-06-18 07:43
2008.08.03
Подскажите, пожалуйста, хороший формат голосовой аудиозаписи.