Форум: "Начинающим";
Текущий архив: 2009.12.20;
Скачать: [xml.tar.bz2];
ВнизПериодический опрос во время работы программы. Найти похожие ветки
← →
kyn66 © (2009-11-02 11:48) [0]Во время работы программы необходимо периодически делать опрос какого либо типа (к примеру наличие файла в некотором каталоге). Если бы программа состояла из одной формы - то понятно было бы, повесил на таймерное событие и все. Но тут в разные моменты времени могут открываться разные модальные формы. Т.е. получается, что вместе с работой программы должен работать некий дополнительный резидент, я так себе это представляю. Или есть другое решение?
← →
CrytoGen (2009-11-02 11:51) [1]таймеры нормально работают, когда открываются модальный окна
← →
brother © (2009-11-02 11:51) [2]> Или есть другое решение?
таймер висит на первой созданной форме...
← →
kyn66 © (2009-11-02 11:56) [3]
> brother © (02.11.09 11:51) [2]
> > Или есть другое решение?таймер висит на первой созданной
> форме...
Т.е. повесить таймер на Main-форму и этого будет достаточно?
← →
Сергей М. © (2009-11-02 11:59) [4]
> периодически делать опрос ...наличие
> файла в некотором каталоге
Дурная затея.
ОС предоставляет механизмы асинхронной польз.нотификации об изменениях в интересующих объектах файловой системы.
← →
brother © (2009-11-02 12:00) [5]> Т.е. повесить таймер на Main-форму и этого будет достаточно?
если [4] для тебя сложно - то да)
← →
kyn66 © (2009-11-02 12:02) [6]
> ОС предоставляет механизмы асинхронной польз.нотификации
> об изменениях в интересующих объектах файловой системы.
Да, знаю про такое. Действительно его можно и применить. Спасибо.
← →
kyn66 © (2009-11-02 17:19) [7]Нашел способ как это сделать с помощью потоков. Однако, не совсем понятно, а как потоку сказать выполнить опрос через указанный промежуток времени, а не постоянно опрашивать.?
← →
clickmaker © (2009-11-02 18:07) [8]> а не постоянно опрашивать.?
H := FindFirstChangeNotification
while not Terminated do
begin
WaitForSingleObject(H, INFINITE);
...
FindNextChangeNotification(H);
end;
FindCloseChangeNotification(H);
← →
Дмитрий Белькевич (2009-11-02 19:07) [9]>WaitForSingleObject(H, INFINITE);
Тред не повиснет??? Думается, что нужно механизмы выхода из бесконечного ожидания продумывать. Например, делать дополнительный event и WaitForMultipleObject.
← →
Leonid Troyanovsky © (2009-11-02 22:00) [10]
> Дмитрий Белькевич (02.11.09 19:07) [9]
> >WaitForSingleObject(H, INFINITE);
> Тред не повиснет??? Думается, что нужно механизмы выхода
> из бесконечного ожидания продумывать.
Все уже придумано до нас.
WaitForSingleObjectEx & QueueUserAPC.
--
Regards, LVT.
← →
Юрий Зотов © (2009-11-02 22:43) [11]Или проще - вместо INFINITE ставить некоторый TimeOut. Выход из цикла и завершение потока произойдут по Terminated.
← →
kyn66 © (2009-11-02 22:55) [12]Честно говоря не совсем понятно о чем идет речь, т.к. никогда не приходилось сталкиваться с такими вещами. Однако век живи - век учись... В моем понятии применение потоков, даже можно подрядить несколько потоков на каждый проверяемый каталог, дает ничто иное, как параллельное выполнение независимых операций. Только вот смысл затеи в том, чтобы запрограммировать эти действия(однократный запрос) через определенный промежуток времени, установленный в параметрах программы. Как это к примеру делается в TheBat - проверка почты через определенный интервал времени.
← →
Юрий Зотов © (2009-11-02 23:16) [13]> kyn66 © (02.11.09 22:55) [12]
> Честно говоря не совсем понятно о чем идет речь
Вы поймете это, как только ознакомитесь в MSDN с описанием функций Find...ChangeNotification и WaitForSingleObject.
В переводе на русский язык это звучит примерно так:
Подписаться на уведомление о первом изменении файла;
Пока поток не прерван, do
begin
Ждать уведомления об изменении файла;
... // Получив это уведомление, что-то сделать
Подписаться на уведомление о следующем изменении файла;
end;
Освободить захваченные ресурсы;
← →
Игорь Шевченко © (2009-11-02 23:36) [14]а бат почту по таймеру проверяет...
← →
kyn66 © (2009-11-02 23:37) [15]
> Юрий Зотов © (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-03 00:35) [16]> 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-03 01:02) [17]
> Юрий Зотов © (03.11.09 00:35) [16]
Согласен. Я попутно уже изучаю. Вот нашел, что если в качестве таймаута поставить INFINITE , то я так понял ожидание будет бесконечным. Однако, уважаемый Юрий Зотов, в [12] я описал сущность своей задчи. В моем случае пауза нужна не для появления события, а самостоятельный опрос каталога на наличие нового файла? Может мне не этот механизм нужен? Что то я уже засомневался по поводу потоков. Может действительно через таймер банально проверить есть-ли новые файлы (а их имена я могу знать) и все на этом. А таймер повесить на главной форме и активировать его, если в параметрах программы это будет установлено.
← →
Юрий Зотов © (2009-11-03 02:06) [18]> kyn66 © (03.11.09 01:02) [17]
Незачем гробить время CPU на периодическую проверку появления в каталоге нового файла, если система сама может об этом сообщить (причем сразу, как только файл появится).
Разве Вам не это нужно?
← →
Германн © (2009-11-03 02:30) [19]
> в [12] я описал сущность своей
> задчи. В моем случае пауза нужна не для появления события,
> а самостоятельный опрос каталога на наличие нового файла?
>
"Y"
> Незачем гробить время CPU на периодическую проверку появления
> в каталоге нового файла, если система сама может об этом
> сообщить (причем сразу, как только файл появится).
>
"Z"
Ну чем не иллюстрация модной в последнее время статьи?
← →
Дмитрий Белькевич (2009-11-03 02:38) [20]
> Или проще - вместо INFINITE ставить некоторый TimeOut. Выход
> из цикла и завершение потока произойдут по Terminated.
Некошерно, ибо потребляет ресурсы... Безусловно лучше, чем постоянная проверка, но неидеально.
← →
Inovet © (2009-11-03 02:53) [21]> [20] Дмитрий Белькевич (03.11.09 02:38)
>
> > Или проще - вместо INFINITE ставить некоторый TimeOut. Выход
> > из цикла и завершение потока произойдут по Terminated.
>
> Некошерно, ибо потребляет ресурсы... Безусловно лучше, чем
> постоянная проверка, но неидеально.
WaitForMultiplyObject() с ...ChangeNotification и Event на завершение.
← →
Вариант (2009-11-03 05:35) [22]
> kyn66 © (03.11.09 01:02) [17]
> а самостоятельный опрос каталога на наличие нового файла
ReadDirectoryChangesW
← →
Юрий Зотов © (2009-11-03 07:42) [23]> Дмитрий Белькевич (03.11.09 02:38) [20]
> Inovet © (03.11.09 02:53) [21]
Чем выход из ожидания по событию лучше выхода из ожидания по таймауту?
> Вариант (03.11.09 05:35) [22]
Асинхронный вызов не годится, т.к. ничего не дает. Синхронный тоже не годится, поскольку можно уйти в бесконечное ожидание. А вот вызвать ReadDirectoryChangesW после выхода из WaiFor... может оказаться полезным (например, если потребуется уточнить, что же произошло).
← →
Inovet © (2009-11-03 08:51) [24]> [23] Юрий Зотов © (03.11.09 07:42)
> > Дмитрий Белькевич (03.11.09 02:38) [20]
> > Inovet © (03.11.09 02:53) [21]
>
> Чем выход из ожидания по событию лучше выхода из ожидания
> по таймауту?
Не будет многократных вызовов WaitFor...() в цикле, и завершение потока произойдет по установке события а не с точностью TimeOut.
← →
Юрий Зотов © (2009-11-03 09:05) [25]> 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 09:19) [26]> [25] Юрий Зотов © (03.11.09 09:05)
> > Inovet © (03.11.09 08:51) [24]
>
> 1. Кто и где установит событие?
1. Тот кто утанавливает Terminated, в цикле вместо проверки Terminated проверяем состояние объекта Event
2-4 из 1 вроде понятны
← →
Inovet © (2009-11-03 09:20) [27]> [26] Inovet © (03.11.09 09:19)
> [25] Юрий Зотов © (03.11.09 09:05)
> И если TimeOut поставить примерно 1 сек (а чаще и вряд ли
> нужно), то нагрузка CPU будет практически нулевой.
Мы тут о кошерности рассуждали.:)
← →
Юрий Зотов © (2009-11-03 09:24) [28]> Inovet © (03.11.09 09:19) [26]
Согласен, так лучше. Хотя практическая разница вряд ли будет заметна.
:o)
← →
kyn66 © (2009-11-03 09:25) [29]
> Юрий Зотов © (03.11.09 02:06) [18]
> > kyn66 © (03.11.09 01:02) [17] Незачем гробить время
> CPU на периодическую проверку появления в каталоге нового
> файла, если система сама может об этом сообщить (причем
> сразу, как только файл появится).
Под периодической подразумевается раз в 10-15 мин, как пожелает юзер. И хочу дополнить... Данная операция нужна для того, чтобы сообщить пользователю о том, что на сервере появились новые файлы для обновления данных. Эти файлы лежат в разных каталогах. Предположим их 4. Так вот, обнаружив новый файл на сервере(сравниваю имя последнего обновленного с текущим) вывожу в низу главной формы информационное окно, в котором указываю строку с наличием файла для обновления. Это дополнительные сведения для принятия механизма обработки.
← →
Сергей М. © (2009-11-03 09:35) [30]
> kyn66 © (03.11.09 09:25) [29]
>
>
В течение этих 10-15 мин новые файлы могут появляться и исчезать много раз. При периодическом сканировании отследить ситуацию их появления и последующего исчезновения невозможно.
← →
Юрий Зотов © (2009-11-03 09:38) [31]> kyn66 © (03.11.09 09:25) [29]
> Эти файлы лежат в разных каталогах. Предположим их 4.
А хоть 104. Разница только в том, что хэндлы уведомлений нужно будет занести в массив, а вместо WaitForSingleObject потребуется WaiForMultipleObjects.
PS
Полагаю, вопрос уже ясен. Есть 2 механизма обнаружения новых файлов - по таймеру и с использованием уведомлений. Если таймер будет тикать раз в 10-15 минут, то для CPU это, конечно, не нагрузка, поэтому можно использовать любой механизм. Решать Вам.
← →
kyn66 © (2009-11-03 09:48) [32]
> Юрий Зотов © (03.11.09 09:38) [31]
Понятно. Большое спасибо за консультацию. :)
← →
Вариант (2009-11-03 10:59) [33]Юрий Зотов © (03.11.09 07:42) [23]
> Асинхронный вызов не годится, т.к. ничего не дает. Синхронный
> тоже не годится, поскольку можно уйти в бесконечное ожидание.
> А вот вызвать ReadDirectoryChangesW после выхода из WaiFor.
> .. может оказаться полезным (например, если потребуется
> уточнить, что же произошло).
Не понял о чем это было. Попробую догадаться.
прошу извинения заранее за плохой телепатор.
Можно сказать, что сам по себе никакой аснхронный метод ничего не дает. Но асинхронный вызов ReadDirectoryDirChangesW отлично работает с WaitFor....позволяя обойтись без FindFirstChangeNotification, + дает дополнительную информацию, если конечно его вызвать до вызова WaitFor.....
В отдельном потоке оба вызова работают нормально. Как синхронный, так и асинхронный. Другое дело, что для прерывания синхронного метода надо извращаться -типа создавать видимость изменений в поисковой директории - это некрасиво, согласен. Но асинхронный вызов метода на мой взгляд вполне пойдет для указанной задачи.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.12.20;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.008 c