Только зацикливанием main можно решить данную задачу или есть более красивое решение?
-
2Быть может имеет смысл подумать в сторону сервисов? – Aleksandr Zharinov Jun 21 '16 at 06:26
-
2На какие именно события? – Jun 21 '16 at 06:29
-
@PashaPash, подключение/отключение внешних дисков. – iluxa1810 Jun 21 '16 at 06:36
-
Для таких целей лучше все таки сервис, вот и статья на тему того как https://habrahabr.ru/post/102826/ – rdorn Jun 21 '16 at 07:33
-
Лень писать ответ - поэтому набросаю сюда ключевых слов. "RegisterDeviceNotification, WM_DEVICECHANGE, невидимая форма, Application.Run()". – Pavel Mayorov Jun 21 '16 at 07:38
-
@PavelMayorov ну кстати, да, можно еще в трей форму свернуть, что-то я не подумал сразу =) – rdorn Jun 21 '16 at 08:11
-
@rdorn, еще, можно очень просто и быстро делать сервисы с помощью TopShelf. – Andrey K. Jun 21 '16 at 12:09
-
@rdorn, в чем преимущество TopShelf ? – iluxa1810 Jun 21 '16 at 13:45
-
Это скорее к @AndreyK. вопрос, но по я так понимаю, что преимущество в том, что часть работы уже сделана, остается только прикрутить нужные декорации и специфический функционал. – rdorn Jun 21 '16 at 13:48
-
@iluxa1810, без TopShelf - геморрой, а с TopShelf - 3 строчки. Отлаживать просто. Делаешь как консольное приложение, потом передаешь параметр (в запуске из командной строки), и оно запускается как служба. Это не альтернатива винсервису, а тот же винсервис. Наизусть не помню, как именно пользоваться, но примерно так. Короче, это супер штука, когда нужно сделать винсервис. – Andrey K. Jun 21 '16 at 15:39
3 Answers
Суть приложения — это выполнение функции Main, пока это приложение должно работать. Соответственно, если приложение должно работать вечно, то не выходить из метода Main — это единственное верное и абсолютно естественное решение.
Пусть вас не обманывают разные платформы вроде Windows.Forms — в конечном счёте ваш код уходит корнем в метод Main в .NET, который уходит корнем во входной адрес в заголовке исполняемого файла. Когда функция завершает выполнение, ось считает процесс выполнившимся.
С точки зрения реализации, конечно, не надо делать while (true) Thread.Sleep(1), вместо это следует по-нормальному дожидаться событий, на которые приложение должно реагировать. Например, если приложение должно реагировать на ввод в консоль, то в цикле можно сделать чтение Console.ReadLine() — эта функция остановит выполнение без пожирания процессорного времени и вернёт строку тогда, когда она есть.
Правда в винде "вечно работающие приложения" обычно делают службами. Служба регистрируется в системном списке служб, получает средства для управления выполнения пользователем, ось следит за запуском и работой службы и т. п. Консоль удобна разве что для отладки, потому что можно выводить журнал сразу в консоль для наглядности. Если приложение должно тесно взаимодействовать с пользователем, ещё можно сделать иконку в области уведомлений.
- 32,103
Консольное приложение не может работать в ФОНЕ. Консоль - это stdin, stdout и stderr. ЛЮБОЕ приложение работающее в фоне обязано отключить эти стандартные файлы.
Такое приложение, в linux терминологии, называется "демоном". На виндовозном языке - "сервис".
Существуют строгие правила написания демонов. Например, как они должны отключаться от консоли. Эти правила изложены во многих местах. Например здесь:
http://citforum.ru/programming/unix/daemons/
Любой демон находится в состоянии ожидания, до тех пор, пока не происходит некоторое событие. Ну, например:
- Демон получил сигнал SIGHUP
- Демон получил извещение от inotify
- Пришло сообщение из канала или очереди сообщений ...
- 97
-
В вопросе спрашивается, очевидно, о Windows, а вы в вашем ответе рассказываете о программировании юниксовских daemon'ов. – VladD Jun 21 '16 at 09:13
-
-
@ixSci: Не, ну формально конечно не вытекает. Но в реальной жизни что-то я не видел среди юниксоидов радостного хайпа по поводу C#, так что в ответе не хватает фразы «В том невероятном случае, если ваша целевая платформа — Linux, ...». – VladD Jun 21 '16 at 09:52
-
по поводу C# Перечитал вопрос ещё раз, но не увидел там слов "C#" или "Windows". Может не туда смотрю?
Писать демона на C# - это круто! :-) Можно, наверное, на РНР попробовать... Может, всё-таки, шурупы - закручивать, а гвозди - забивать ?
– Сергей Jun 21 '16 at 10:13 -
@Сергей, смотрите какие теги у вопроса(голубые прямоугольники в вопросе) – ixSci Jun 21 '16 at 11:17
-
Или я смотрю не туда, или мы вообще о разном говорим! :-(
Я вижу в заголовке:
"Как сделать консольное приложение, которое бесконечно работает в фоне и реагирует на события?"
О каких голубых прямоугольниках вы говорите? Можно скриншот глянуть, как это у Вас выглядит ?
– Сергей Jun 22 '16 at 04:45 -
Во-первых работающее в фоне приложение конечно должно быть сервисом (Windows Service). Но полезно реализовать двоякий режим -- чтобы можно было также запустить с командной строки -- нужно для проверок и отладки.
Во-вторых, нужен шедулер (scheduler) -- часть программы которая отвечает за вызов задач (tasks, jobs) по расписанию или по внешним событиям. Шедулер лучше взять готовый (например, Quartz.net) -- чтобы не наступать снова на все те же самые грабли.
- 1,868