![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Периодический опрос во время работы программы. [D7, WinXP]
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]а бат почту по таймеру проверяет...