Главная страница
    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.49 MB
Время: 0.006 c
2-1215197594
who5
2008-07-04 22:53
2008.08.03
Две формы


2-1214932363
Pasha L
2008-07-01 21:12
2008.08.03
Есть ли аналог FillChar, работающий с шагом более единицы


2-1214779198
Андрей_1
2008-06-30 02:39
2008.08.03
Exel в Paradox


2-1215085766
lead-in
2008-07-03 15:49
2008.08.03
CreateProcess


15-1213881136
Ega23
2008-06-19 17:12
2008.08.03
packed object - в какой версии Delphi появился?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский