Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.08.03;
Скачать: [xml.tar.bz2];

Вниз

завершение 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.01 c
15-1213817580
wl
2008-06-18 23:33
2008.08.03
проверка сайтов на вшивость


4-1193603602
rainbow_d
2007-10-28 23:33
2008.08.03
Получить содержимое заблокированного файла


15-1213818601
Сергей_77
2008-06-18 23:50
2008.08.03
Ошибка установки, как побороть.


15-1213859829
antarion
2008-06-19 11:17
2008.08.03
Вакансия программиста Delphi


10-1139646655
_Seldon_
2006-02-11 11:30
2008.08.03
Delphi+Visio





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский