Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.12.20;
Скачать: CL | DM;

Вниз

Периодический опрос во время работы программы.   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.012 c
2-1257243276
kyn66
2009-11-03 13:14
2009.12.20
Ошибка в коде, который раньше работал.


15-1255470552
Германн
2009-10-14 01:49
2009.12.20
Ещё один дурацкий вопрос. Intel vs AMD.


15-1255770792
Вайка
2009-10-17 13:13
2009.12.20
S. T. A. L. K. E. R. Зов Припяти. Как Вам?


6-1209028510
ivanov
2008-04-24 13:15
2009.12.20
3агрузить страницу с подменой своего стиля


2-1257362090
bagi
2009-11-04 22:14
2009.12.20
создание профилей настроек