Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Периодический опрос во время работы программы. [D7, WinXP]


Страницы:   1 2

kyn66 ©   (2009-11-02 11:48:00) 

Во время работы программы необходимо периодически делать опрос какого либо типа (к примеру наличие файла в некотором каталоге). Если бы программа состояла из одной формы - то понятно было бы, повесил на таймерное событие и все. Но тут в разные моменты времени могут открываться разные модальные формы. Т.е. получается, что вместе с работой программы должен работать некий дополнительный резидент, я так себе это представляю. Или есть другое решение?


Вариант   (2009-11-03 10:59:00) [1]

Юрий Зотов ©   (03.11.09 07:42) [23]


> Асинхронный вызов не годится, т.к. ничего не дает. Синхронный
> тоже не годится, поскольку можно уйти в бесконечное ожидание.
>  А вот вызвать ReadDirectoryChangesW после выхода из WaiFor.
> .. может оказаться полезным (например, если потребуется
> уточнить, что же произошло).

Не понял о чем это было. Попробую догадаться.
прошу извинения заранее за плохой телепатор.

 Можно сказать, что сам по себе никакой аснхронный метод ничего не дает. Но асинхронный вызов ReadDirectoryDirChangesW отлично работает с WaitFor....позволяя обойтись без FindFirstChangeNotification, + дает дополнительную информацию, если конечно его вызвать до вызова WaitFor.....

В отдельном потоке оба вызова работают нормально. Как синхронный, так и асинхронный. Другое дело, что для прерывания синхронного метода надо извращаться -типа создавать видимость изменений в поисковой директории - это некрасиво, согласен. Но асинхронный вызов метода на мой взгляд вполне пойдет для указанной задачи.


kyn66   (2009-11-03 09:48:00) [2]


> Юрий Зотов ©   (03.11.09 09:38) [31]


Понятно. Большое спасибо за консультацию. :)


Юрий Зотов   (2009-11-03 09:38:00) [3]

> kyn66 ©   (03.11.09 09:25) [29]

> Эти файлы лежат в разных каталогах. Предположим их 4.

А хоть 104. Разница только в том, что хэндлы уведомлений нужно будет занести в массив, а вместо WaitForSingleObject потребуется WaiForMultipleObjects.

PS
Полагаю, вопрос уже ясен. Есть 2 механизма обнаружения новых файлов - по таймеру и с использованием уведомлений. Если таймер будет тикать раз в 10-15 минут, то для CPU это, конечно, не нагрузка, поэтому можно использовать любой механизм. Решать Вам.


Сергей М.   (2009-11-03 09:35:00) [4]


> kyn66 ©   (03.11.09 09:25) [29]
>
>


В течение этих 10-15 мин новые файлы могут появляться и исчезать много раз. При периодическом сканировании отследить ситуацию их появления и последующего исчезновения невозможно.


kyn66   (2009-11-03 09:25:00) [5]


> Юрий Зотов ©   (03.11.09 02:06) [18]
> > kyn66 ©   (03.11.09 01:02) [17]  Незачем гробить время
> CPU на периодическую проверку появления в каталоге нового
> файла, если  система сама может об этом сообщить (причем
> сразу, как только файл появится).


Под периодической подразумевается раз в 10-15 мин, как пожелает юзер. И хочу дополнить... Данная операция нужна для того, чтобы сообщить пользователю о том, что на сервере появились новые файлы для обновления данных. Эти файлы лежат в разных каталогах. Предположим их 4. Так вот, обнаружив новый файл на сервере(сравниваю имя последнего обновленного с текущим) вывожу в низу главной формы информационное окно, в котором указываю строку с наличием файла для обновления. Это дополнительные сведения для принятия механизма обработки.


Юрий Зотов   (2009-11-03 09:24:00) [6]

> Inovet ©   (03.11.09 09:19) [26]

Согласен, так лучше. Хотя практическая разница вряд ли будет заметна.
:o)


Inovet   (2009-11-03 09:20:00) [7]

> [26] Inovet ©   (03.11.09 09:19)


> [25] Юрий Зотов ©   (03.11.09 09:05)
> И если TimeOut поставить примерно 1 сек (а чаще и вряд ли
> нужно), то нагрузка CPU будет практически нулевой.

Мы тут о кошерности рассуждали.:)


Inovet   (2009-11-03 09:19:00) [8]

> [25] Юрий Зотов ©   (03.11.09 09:05)
> > Inovet ©   (03.11.09 08:51) [24]
>
> 1. Кто и где установит событие?

1. Тот кто утанавливает Terminated, в цикле вместо проверки Terminated проверяем состояние объекта Event
2-4 из 1 вроде понятны


Юрий Зотов   (2009-11-03 09:05:00) [9]

> Inovet ©   (03.11.09 08:51) [24]

1. Кто и где установит событие?

2. Что будет, если оно так и останется неустановленным?

3. При появлении файла завершать поток не надо, а надо обработать его и отслеживать дальше - поэтому цикл с WaitFor все равно нужен. И нет никакой разницы, будет ли это цикл с WaitForSingleObject или цикл с WaitForMultiplyObject.

4. В варианте с TimeOut срабатывание происходит точно так же, по уведомлению, а вовсе не с точностью TimeOut. А TimeOut нужен лишь для периодической проверки Terminated - то есть, для того, чтобы программа в любой момент могла нормально завершиться. И если TimeOut поставить примерно 1 сек (а чаще и вряд ли нужно), то нагрузка CPU будет практически нулевой.


Inovet   (2009-11-03 08:51:00) [10]

> [23] Юрий Зотов ©   (03.11.09 07:42)
> > Дмитрий Белькевич   (03.11.09 02:38) [20]
> > Inovet ©   (03.11.09 02:53) [21]
>
> Чем выход из ожидания по событию лучше выхода из ожидания
> по таймауту?

Не будет многократных вызовов WaitFor...() в цикле, и завершение потока произойдет по установке события а не с точностью TimeOut.


Юрий Зотов   (2009-11-03 07:42:00) [11]

> Дмитрий Белькевич   (03.11.09 02:38) [20]
> Inovet ©   (03.11.09 02:53) [21]

Чем выход из ожидания по событию лучше выхода из ожидания по таймауту?

> Вариант   (03.11.09 05:35) [22]

Асинхронный вызов не годится, т.к. ничего не дает. Синхронный тоже не годится, поскольку можно уйти в бесконечное ожидание. А вот вызвать ReadDirectoryChangesW после выхода из WaiFor... может оказаться полезным (например, если потребуется уточнить, что же произошло).


Вариант   (2009-11-03 05:35:00) [12]


> kyn66 ©   (03.11.09 01:02) [17]


>  а самостоятельный опрос каталога на наличие нового файла


ReadDirectoryChangesW


Inovet   (2009-11-03 02:53:00) [13]

> [20] Дмитрий Белькевич   (03.11.09 02:38)
>
> > Или проще - вместо INFINITE ставить некоторый TimeOut. Выход
> > из цикла и завершение потока произойдут по Terminated.
>
> Некошерно, ибо потребляет ресурсы... Безусловно лучше, чем
> постоянная проверка, но неидеально.

WaitForMultiplyObject() с ...ChangeNotification и Event на завершение.


Дмитрий Белькевич   (2009-11-03 02:38:00) [14]


> Или проще - вместо INFINITE ставить некоторый TimeOut. Выход
> из цикла и завершение потока произойдут по Terminated.


Некошерно, ибо потребляет ресурсы... Безусловно лучше, чем постоянная проверка, но неидеально.


Германн   (2009-11-03 02:30:00) [15]


> в [12] я описал сущность своей
> задчи. В моем случае пауза нужна не для появления события,
>  а самостоятельный опрос каталога на наличие нового файла?
>  

"Y"


> Незачем гробить время CPU на периодическую проверку появления
> в каталоге нового файла, если  система сама может об этом
> сообщить (причем сразу, как только файл появится).
>

"Z"
Ну чем не иллюстрация модной в последнее время статьи?


Юрий Зотов   (2009-11-03 02:06:00) [16]

> kyn66 ©   (03.11.09 01:02) [17]  

Незачем гробить время CPU на периодическую проверку появления в каталоге нового файла, если  система сама может об этом сообщить (причем сразу, как только файл появится).

Разве Вам не это нужно?


kyn66   (2009-11-03 01:02:00) [17]


> Юрий Зотов ©   (03.11.09 00:35) [16]


Согласен. Я попутно уже изучаю. Вот нашел, что если в качестве таймаута поставить INFINITE, то я так понял ожидание будет бесконечным. Однако, уважаемый Юрий Зотов, в [12] я описал сущность своей задчи. В моем случае пауза нужна не для появления события, а самостоятельный опрос каталога на наличие нового файла? Может мне не этот механизм нужен? Что то я уже засомневался по поводу потоков. Может действительно через таймер банально проверить есть-ли новые файлы (а их имена я могу знать) и все на этом. А таймер повесить на главной форме и активировать его, если в параметрах программы это будет установлено.


Юрий Зотов   (2009-11-03 00:35:00) [18]

> kyn66 ©   (02.11.09 23:37) [15]

> если "уведомления" не было, то до этой строки
> ... Получив это уведомление, что-то сделать
> дело может и не дойти?

Может, если при вызове WaitForSingleObject Вы не проставите таймаут. А если проставите, то дойдет обязательно.

Может быть, есть смысл все же ознакомиться с описанием функций, а уж потом продолжить разговор? Просто после ознакомления многие вопросы отпадут сами собой, а обсуждение будет гораздо более плодотворным.

Вот предлагаемая к изучению и обсуждению схема:

procedure TMyThread.Execute;
const
 TimeOut = ...;
var
 H: THandle;
begin
 H := FindFirstChangeNotification(...);
 if (H <> INVALID_HANDLE_VALUE) and (H <> ERROR_INVALID_FUNCTION) then
 try
   while not Terminated do
   begin
     if WaitForSingleObject(H, TimeOut) = WAIT_OBJECT_0 then
       ... // Обрабатываем уведомление
     FindNextChangeNotification(H)
   end
 finally
   FindCloseChangeNotification(H)
 end
end;


kyn66   (2009-11-02 23:37:00) [19]


> Юрий Зотов ©   (02.11.09 23:16) [13]


Т.е. это перевод вот этого куска

H := FindFirstChangeNotification
while not Terminated do
begin
WaitForSingleObject(H, INFINITE);
...
FindNextChangeNotification(H);
end;
FindCloseChangeNotification(H);


Ждать уведомления об изменении файла;оно же WaitForSingleObject(H, INFINITE)бутет ожидать на этой строке, пока не произойдет какое либо событие? В моем случае пока не появится в каталоге файл? Т.е. если "уведомления" не было, то до этой строки ... // Получив это уведомление, что-то сделатьдело может и не дойти?


Игорь Шевченко   (2009-11-02 23:36:00) [20]

а бат почту по таймеру проверяет...


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо