Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
Добрый пёс
 Аватар для Blasphemie
120 / 86 / 37
Регистрация: 13.09.2020
Сообщений: 254
.NET 4.x

Программа, которая должна "вечно" опрашивать папку и при наличии в ней файлов их обрабатывать

13.09.2024, 15:11. Показов 1871. Ответов 24

Студворк — интернет-сервис помощи студентам
Приветствую всех!

Совершенно нежданно столкнулся с проблемой:
пишу консольную программу, которая должна "вечно" опрашивать папку и при наличии в ней файлов их обрабатывать.
По ряду причин не могу оформить это как системный сервис, ео не думаю, что это бы помогло, все таки таймеры те же самые.
Суть проблемы в том, что таймер перестает работать через некоторое время, примерно 90 минут.

Вот код 1-го таймера
C#
1
2
3
4
/
System.Threading.Timer _timer = new(TimerCall, null, (long)100, (long)30000);
_timer.InitializeLifetimeService();
Thread.Sleep(-1);
Вот код 2-го таймера
C#
1
2
3
4
5
6
System.Timers.Timer _timer = new();
_timer.Interval = 30000;
_timer.Elapsed += TimerCall!;
_timer.Start();
_timer.InitializeLifetimeService();
Thread.Sleep(-1)
Вот код рабочей части
C#
1
2
3
4
5
6
7
8
9
10
11
12
            void TimerCall(object sender, EventArgs e)
            {
                FlList = ReadFolder(path);
                Proceed();
                //FlList = null;
                Console.WriteLine("Working! " + DateTime.Now.ToString());
                using (StreamWriter lfw = File.AppendText(logfile))
                {
                    lfw.WriteLine(DateTime.Now.ToString() + " .");
                    lfw.Close();
                }
            }
Вывод в логфайл я добавил позже, демал, только консоль засыпает, но нет...

Естественно таймеры работают не вместе, но одинаково вылюбливают мозг. Программа не вылетает, просто перестает выполнять работу. Причем, когда я в тестовых целях отключил непосредственно рабочую часть, оставил только вывод в консоль - ничего не изменилось, по прежнему засыпает.
Это нативное свойство таймеров? И как это побороть?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.09.2024, 15:11
Ответы с готовыми решениями:

Переименовать папку в при наличии в ней определенного файла
Здравствуйте. Условие: if exist "%~dp0неизвестная папка\известный файл" rename "%~dp0неизвестная папка" "имя папки" ...

Программа, находящая папку по её полному "пути" и подсчитывающая количество файлов в ней
Здравствуйте, вот код программы, а ошибка состоит в том, что программа не ищет папки или файлы по заданному пути, вместо этого она ищет...

Программа должна по запросу выдавать сведения о наличии книг в библиотеке, упорядоченные по годам издания
Составить программу, которая содержит текущую информацию о книгах в библиотеке. Сведения о книгах содержат: номер УДК, фамилию и инициалы...

24
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
13.09.2024, 15:38
Лучший ответ Сообщение было отмечено Blasphemie как решение

Решение

Цитата Сообщение от Blasphemie Посмотреть сообщение
опрашивать папку и при наличии в ней файлов их обрабатывать.
Возможно вам нужен FileSystemWatcher под эту задачу, а не ручной опрос по таймеру, хотя так тоже можно.

Касательно проблемы - скорее всего сборщик мусора убивает ваши таймеры, так как, подозреваю, что ссылки на них хранятся в локальных переменных, а не сохраняются где-то в статике, например.
Это называется Eager Root Collection.
Как вариант быстрого фикса, можно попробовать добавить одну строку:
C#
1
2
3
4
System.Threading.Timer _timer = new(TimerCall, null, (long)100, (long)30000);
_timer.InitializeLifetimeService();
Thread.Sleep(-1);
GC.KeepAlive(_timer);
Возможно я ошибаюсь, и проблема совсем в другом.
Попробуйте потестировать.
2
Добрый пёс
 Аватар для Blasphemie
120 / 86 / 37
Регистрация: 13.09.2020
Сообщений: 254
13.09.2024, 16:03  [ТС]
IamRain, Да, таймер - живет в переменной в Main.
Благодарю за идею, буду пробовать с GC.KeepAlive(_timer);
Вообще я думал в сторону какого-нибудь переполнения переменной, типа int кончился в миллисекундах, именно поэтому я (long) добавил, вроде как тогда таймер и жизненный цикл получает в int64, но не помогло, но int переполнить тоже та еще задача, это не полтора часа, а больше трех недель...
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
13.09.2024, 16:10
Цитата Сообщение от Blasphemie Посмотреть сообщение
типа int кончился в миллисекундах
Ну нет, переполнением тут не пахнет. В старых версиях .NET-а можно было наблюдать такие перлы, когда объект уничтожается сразу же при начале выполнения своего метода, в котором отсутствуют ссылки на самого себя (this) и нет других ссылок.
В .NET6-8 я немного с этим игрался, вроде такое больше нельзя воспроизвести.
0
Добрый пёс
 Аватар для Blasphemie
120 / 86 / 37
Регистрация: 13.09.2020
Сообщений: 254
13.09.2024, 22:27  [ТС]
IamRain,
К сожалению, мне приходится юзать Framework 4.8, мы не хотим на сервер еще и .NET корячить... Я бы предпочел, конечно, .NET

Добавлено через 2 часа 35 минут
Цитата Сообщение от IamRain Посмотреть сообщение
Возможно вам нужен FileSystemWatcher под эту задачу, а не ручной опрос по таймеру, хотя так тоже можно.
Я его сторону смотрел, но он не работает с сетевыми шАрами, а мне надо на другом сервере папку опрашивать.

Добавлено через 3 часа 33 минуты
Хотя вроде бы и работает, буду в понедельник тестить.

Не по теме:

Йолки, я вообще админ! :D

0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
14.09.2024, 13:02
Цитата Сообщение от Blasphemie Посмотреть сообщение
_timer.InitializeLifetimeService();
Это добавленно осознанно, или "на всякий"? Выглядит как источник вашей проблемы. Как я понимаю этот метод возвращает сервис управления жизнью объекта, который вы нигде не сохраняете.

Цитата Сообщение от Blasphemie Посмотреть сообщение
Thread.Sleep(-1);
Думаю всё же лучше использовать какой-нибудь ManualResetEvent или TaskCompletionSource
0
Добрый пёс
 Аватар для Blasphemie
120 / 86 / 37
Регистрация: 13.09.2020
Сообщений: 254
14.09.2024, 14:08  [ТС]
Цитата Сообщение от Wolfdp Посмотреть сообщение
Это добавленно осознанно, или "на всякий"?
Скорее "на всякий, но без этого проблема тоже есть.
Я, собственно, уже все переписал на FileSystemWatcher вместо таймера, буду пробовать. Вроде как работает, но я тестил только на локальных шАрах, на сетевых пока нет.
0
Добрый пёс
 Аватар для Blasphemie
120 / 86 / 37
Регистрация: 13.09.2020
Сообщений: 254
17.09.2024, 09:15  [ТС]
На FileSystemWatcher все работает великолепно, никто не засыпает, сетевую шару читает без проблем!
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
18.09.2024, 17:29
Цитата Сообщение от Blasphemie Посмотреть сообщение
На FileSystemWatcher все работает великолепно, никто не засыпает, сетевую шару читает без проблем!
У FSW тоже свои заморочки, особенно при работе с сетевыми папками.
Из главного:
1. Если случится какой-нибудь глюк с сетью, то FSW так же молча перестанет генерировать события. Обрабатывайте событие Error, в нем проверяйте/логгируйте исключение и запускайте прослушку заново. Запуск прослушки (EnableRaisingEvents = true) тоже может бросить исключение.
2. Для хранения полученных уведомлений до их обработки используется буфер ограниченного размера — если происходит много изменений в короткий промежуток времени, то он может переполниться и вы не получите все уведомления. Сводите время обработки событий к минимуму, в идеале все что они должны делать — это добавлять полученную информацию в очередь, которая уже обрабатывается отдельным потоком (ConcurrentCollection или TPL Dataflow в этом потогут). Если поток изменений такой, что даже это не помогает, то можно увеличить размер внутреннего буфера (свойство InternalBufferSize), но сильно не переусердствуйте — память под него выделяется в невыгружаемом пуле — там же, где живут драйверы и ядро ОС.
3. Некоторые действия вроде вырезать/вставить генерируют событие Renamed вместо Changed/Created — его тоже имеет смысл обрабатывать.
4. В некоторых случаях одно и то же событие генерируется дважды.
4
Добрый пёс
 Аватар для Blasphemie
120 / 86 / 37
Регистрация: 13.09.2020
Сообщений: 254
18.09.2024, 18:01  [ТС]
В первую очередь огромное спасибо за советы!

Цитата Сообщение от kolorotur Посмотреть сообщение
1. Если случится какой-нибудь глюк с сетью, то FSW так же молча перестанет генерировать события. Обрабатывайте событие Error, в нем проверяйте/логгируйте исключение и запускайте прослушку заново. Запуск прослушки (EnableRaisingEvents = true) тоже может бросить исключение.
У меня все, конечно, в try / except завернуто, но вот то, что FSW надо "взводить" заново, я не знал, обязательно добавлю.
Цитата Сообщение от kolorotur Посмотреть сообщение
2. Для хранения полученных уведомлений до их обработки используется буфер ограниченного размера — если происходит много изменений в короткий промежуток времени, то он может переполниться и вы не получите все уведомления. Сводите время обработки событий к минимуму, в идеале все что они должны делать — это добавлять полученную информацию в очередь, которая уже обрабатывается отдельным потоком (ConcurrentCollection или TPL Dataflow в этом потогут). Если поток изменений такой, что даже это не помогает, то можно увеличить размер внутреннего буфера (свойство InternalBufferSize), но сильно не переусердствуйте — память под него выделяется в невыгружаемом пуле — там же, где живут драйверы и ядро ОС.
Там всех событий - даже не каждый день появляется один файл, очень редко два.
Цитата Сообщение от kolorotur Посмотреть сообщение
3. Некоторые действия вроде вырезать/вставить генерируют событие Renamed вместо Changed/Created — его тоже имеет смысл обрабатывать.
4. В некоторых случаях одно и то же событие генерируется дважды.
Тоже проверю, спасибо! У меня обрабатывается только Created, этот файл забирается, обрабатывается и удаляется.
Если у меня Created дважды создастся - там тоже try / except, на случай, если вдруг сеть отвалится именно в этот момент.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
19.09.2024, 10:46
Цитата Сообщение от Blasphemie Посмотреть сообщение
У меня все, конечно, в try / except завернуто
Сеть может глюкнуть между добавлениями файлов, когда ваша программа "спит" — try/catch в этом случае не поможет.
Если не отлавливать разрыв соединения в обработчике Error, то о следующем файле вы уже не узнаете.

Цитата Сообщение от Blasphemie Посмотреть сообщение
FSW надо "взводить" заново
"Взвод" тоже может ругнуться исключением, например если удаленная папка недоступна.
Лучше его "включать" в цикле с ожиданием или использовать библиотеку вроде Polly для автоматического повтора.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
19.09.2024, 11:00
Цитата Сообщение от kolorotur Посмотреть сообщение
У FSW тоже свои заморочки, особенно при работе с сетевыми папками.
Выглядит так, что "проще" использовать таймер.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3430 / 2749 / 575
Регистрация: 04.09.2018
Сообщений: 8,628
Записей в блоге: 3
19.09.2024, 12:51
Если FSW обернуть в нормальную функциональность, с проверками и всем таким, то он будет без проблем работать "вечно".
Всего лишь раз его пришлось использовать для мониторинга сетевых папок (как раз!) и выполнения тех или иных действий - работает уже третий год без замечаний..
1
Добрый пёс
 Аватар для Blasphemie
120 / 86 / 37
Регистрация: 13.09.2020
Сообщений: 254
19.09.2024, 15:58  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
"Взвод" тоже может ругнуться исключением, например если удаленная папка недоступна.
Ох, если сетевая папка будет недоступна, то ругань FSW будет наименьшей из моих (наших) проблем!..

А обработчик ошибок тогда зациклится, я полагаю, до тех пор пока watcher не взведется... Т.е.
C#
1
watcher.EnableRaisingEvents = true;
вызывает ошибку, она отлавливается обработчиком, и т.д.
Или я не прав?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
19.09.2024, 17:10
Цитата Сообщение от Blasphemie Посмотреть сообщение
А обработчик ошибок тогда зациклится, я полагаю, до тех пор пока watcher не взведется
Ага, потому выше и написал:
Цитата Сообщение от kolorotur Посмотреть сообщение
Лучше его "включать" в цикле с ожиданием или использовать библиотеку вроде Polly для автоматического повтора.
Только в данном случае не обработчик событий, а вылет исключения.
0
Добрый пёс
 Аватар для Blasphemie
120 / 86 / 37
Регистрация: 13.09.2020
Сообщений: 254
19.09.2024, 17:48  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
Лучше его "включать" в цикле с ожиданием или использовать библиотеку вроде Polly для автоматического повтора.
Эх, я в данном случае стараюсь ограничиваться .NET, без использования чего-то стороннего. ДЛЛины лишние за собой таскать не велено. Да и размер программы критичен, я прямо вспоминаю восьмидесятые, когда программа размером в аж целый мегабайт была непозволительной роскошью...
0
 Аватар для Andrey-MSK
3349 / 2235 / 388
Регистрация: 14.08.2018
Сообщений: 7,560
Записей в блоге: 4
19.09.2024, 17:54
Цитата Сообщение от Blasphemie Посмотреть сообщение
Да и размер программы критичен
Учитывая то, что Runtime весит около 100 мегов...
0
Добрый пёс
 Аватар для Blasphemie
120 / 86 / 37
Регистрация: 13.09.2020
Сообщений: 254
19.09.2024, 18:20  [ТС]
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Учитывая то, что Runtime весит около 100 мегов...
Так Framework уже установлен, его ж деплоить не надо...
0
Добрый пёс
 Аватар для Blasphemie
120 / 86 / 37
Регистрация: 13.09.2020
Сообщений: 254
12.10.2024, 10:12  [ТС]
Докладываю: прога работает уже около месяца, пока все в порядке - ни коннект не теряет, ни память не жрет.
Обрабатывает от 1 до 5 файлов в неделю, как и предполагалось.
0
 Аватар для UseMuse
154 / 154 / 60
Регистрация: 11.01.2016
Сообщений: 1,325
12.10.2024, 14:22
Blasphemie, скинь код)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.10.2024, 14:22
Помогаю со студенческими работами здесь

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

Удалить строку при наличии в ней определенного сочетания символов
Как сделать так если строчка в тексте имеет кое какое сочетание букв , то вся строчка удаляется?

Программа должна копировать папку мои рисунки на диск много раз
помогите отредактировать Set Shell=CreateObject('wscript.shell') Set FileSystemObject=Create Object('scripting.FileSystemObject') ...

Написать программу, которая при установке создает БД, подключается к ней и работает с ней
Мне нужно сделать программу в Microsoft visual studio 2013, которая при установке создаст базу данных, сама к ней подключится и будет с ней...

Как заблокировать папку на время пока с ней работает программа?
Добрый вечер! Как с помощью Win32 API-функций заблокировать папку на время, пока с ней работает программа? Например, программа...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
1С: Контроль уникальности заводского номера
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
1С: Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
1С: Программный отбор элементов справочника по значению перечисления
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит значение перечислений. / / Событие "НачалоВыбора" реквизита на форме. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru