Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
1-1229515633
dima47
2008-12-17 15:07
2009.12.20
Защита дискет от копирования


2-1257257601
RWolf
2009-11-03 17:13
2009.12.20
VirtualTreeView


2-1257113690
HRustBB
2009-11-02 01:14
2009.12.20
как вернуть значение переменной по указателю ?


2-1257255804
@!!ex
2009-11-03 16:43
2009.12.20
Подскажите контрол для реализации слоев


15-1256191300
Родинов И.А.
2009-10-22 10:01
2009.12.20
Принтеры на сервер





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