Консольное приложение С# — продолжайте работать

Я собираюсь разработать консольное приложение, которое необходимо будет постоянно запускать и выполнять работу в определенное время.

Мой вопрос: каковы наилучшие методы или практики для поддержания вашего приложения в рабочем состоянии?

Мои мысли были: Цикл, который никогда не заканчивается? Таймер, который спит, а затем при необходимости переходит к рутине (после установленного периода ожидания)?

Я буду компилировать приложение в исполняемый файл, а затем запускать его как службу, используя AlwaysUp.

С Уважением..

Питер


person Community    schedule 30.03.2009    source источник
comment
Причина, по которой вы получили так много разных ответов, заключается в том, что вы не предоставили достаточно информации о том, что эта штука будет делать. Имея больше информации, вы сможете сузить некоторые из представленных вариантов.   -  person Cheeso    schedule 30.03.2009


Ответы (11)


Лучшим решением было бы написать консольное приложение, которое выполняет свою работу и завершает работу. Затем вы можете использовать планировщик заданий Windows для его периодического запуска.

person Community    schedule 30.03.2009
comment
Абсолютно согласен! Некоторое время назад Джон Галлоуэй написал в блоге сообщение, которое убедило меня в том, что я поступал неправильно, создавая службу вместо задачи: weblogs.asp.net/jgalloway/archive/2005/10/24/428303.aspx - person Neil Williams; 30.03.2009
comment
Я думаю, что сервисы предлагают больше гибкости с точки зрения учетных данных пользователя. - person ojblass; 30.03.2009
comment
По крайней мере, насколько я видел, вы можете установить учетные данные, под которыми будет выполняться запланированное задание. Что можно сделать с услугой, чего нельзя сделать с задачей? - person Neil Williams; 30.03.2009
comment
Суть в том, что мы не знаем, потому что ОП не сказал нам, что он на самом деле пытается сделать. - person i_am_jorf; 30.03.2009

Почему бы вам не создать свое приложение как услугу в первую очередь?

person Chris W. Rea    schedule 30.03.2009

Хотя вам действительно следует использовать для этого службу, если вам все равно нужно/хотите это сделать, вы можете использовать ManualResetEvent для этого:

private ManualResetEvent Wait = new ManualResetEvent(false);

Когда вы закончите «начинать» и захотите просто подождать, вы должны сделать:

Wait.WaitOne();

Когда вы хотите остановить и позволить ему выйти, вы можете сделать:

Wait.Set();
person PhonicUK    schedule 04.12.2015

Вы, вероятно, не хотите просто вращаться в цикле, без необходимости потребляя процессорное время.

Предполагая, что вы работаете в Windows, у вас должен быть цикл, который никогда не заканчивается вызовом WaitForSingleObject() или WaitForMultipleObjects() или MsgWaitForMultipleObjects() в зависимости от ваших потребностей. Затем создайте какой-нибудь объект синхронизации, который вас разбудит, например именованное событие.

См. документацию по синхронизации Win32 здесь. Если вы подробнее расскажете о том, что должна делать ваша программа, мы, вероятно, сможем дать более конкретный совет.

person i_am_jorf    schedule 30.03.2009
comment
Привет, спасибо за обновление, причина, по которой я выбрал это как консольное приложение, заключается в том, что оно дает мне возможность запускать его вручную в любое время. Приложение будет читать файл конфигурации и выполнять чтение/обработку файла в заданное время на основе информации, хранящейся в файле конфигурации. - person ; 02.04.2009
comment
Также потребуется отправить предупреждение по электронной почте, если файл отсутствует в каталоге certian. Если файл существует, его необходимо открыть и прочитать в поисках ошибок, любых ошибок, а затем также необходимо отправить электронное письмо с предупреждением. - person ; 02.04.2009

Вы можете добавить ссылку на System.Windows.Forms и вызвать System.Windows.Forms.Application.Run(), чтобы начать стандартный цикл сообщений приложения. Ctrl-C завершит работу приложения.

Другой вариант — использовать Console.ReadKey(), чтобы приостановить приложение. Нравится Console.WriteLine("Press [ANY] key to quit..."); Console.ReadKey();

Это то, что я использую в своих консольных приложениях, когда они просто сидят и ждут, когда произойдут события. В любом случае приложение будет продолжать работать и перехватывать инициированные события (например, от таймера, WCF, FileWatcher и т. д.).

person noahcoad    schedule 04.03.2013

Код, который работает постоянно, называется демоном, и есть статья здесь описано, как делать то, что вы просите. Это покажет вам пример того, как написать простую службу здесь.

person ojblass    schedule 30.03.2009
comment
Да, я думал о сервисе, но не думаю, что он удовлетворит мои потребности, поскольку мне нужно обрабатывать файлы и считывать информацию о конфигурации из сохраненного файла, чтобы работать в определенное время, как указано в файле конфигурации. - person ; 02.04.2009

Если ваша программа будет работать постоянно, вы должны спать до тех пор, пока не произойдет желаемое событие (например, пройдет XX секунд). Если вы просто вращаетесь в цикле while {}, вы будете поглощать процессорное время.

Если ваша программа будет всегда работать на машине, вам следует подумать о том, чтобы сделать ее службой, чтобы она автоматически запускалась и останавливалась вместе с машиной.

person Andrew Grant    schedule 30.03.2009

Ну, я уверен, что в какой-то момент это должно прекратиться, нет?

Создайте поток, который действительно работает, и создайте основной блок потока в Console.ReadLine(), если вы хотите, чтобы его можно было запускать и как консольное приложение.

Если вы действительно хотите навсегда приостановить основной поток, просто заблокируйте событие ManualResetEvent, которое вы никогда не запускаете.

Но подумайте об использовании сервиса, если можете.

person MichaelGG    schedule 30.03.2009

Если вы создаете настольное приложение, вам нужно, чтобы оно запускалось в системном трее. Это будет

  1. Предотвратите случайное закрытие приложения вашими пользователями
  2. Не позволяйте вашему приложению загромождать экран ваших пользователей

Если вы создаете серверное приложение, вам нужно написать службу Windows. Это будет

  1. Не позволяйте администратору случайно закрыть ваше приложение
  2. Устраните необходимость в том, чтобы на сервере кто-то входил в консоль для запуска вашего приложения.

Как человек, который в первую очередь является ИТ-специалистом, я бы сказал, что сторонние приложения, которые мы получаем, которые работают как консольные приложения, а не службы Windows, мы прилагаем много усилий, чтобы их не купили. Это создает для нас много работы и открывает серьезные проблемы с поддержкой и дыры в безопасности.

person Steve Evans    schedule 30.03.2009

Отправка потока в спящий режим: System.Threading.Thread.Sleep(10000);

Ожидание нажатия клавиши: Console.WriteLine("Нажмите любую клавишу, чтобы продолжить..."); Консоль.Прочитать();

person amir    schedule 25.10.2011
comment
Спящий режим потока замедляет работу программного обеспечения и не должен использоваться. Вы должны использовать AutoResetSignal для консольного приложения или создать службу, если она должна работать все время. - person Piotr Kula; 28.01.2015

Создайте задачу, а затем подождите.

class Program
{
    static void Main(string[] args)
    {
        var processTask = Process();
        processTask.Wait();
    }

    private static async Task Process()
    {
        var isNotCancelled = true;

        while (isNotCancelled)
        {
            //Polling time here
            await Task.Delay(1000);

            //TODO: Do work here and listen for cancel
            Console.WriteLine("I did  some work...");
        }
    }
}
person Christian Findlay    schedule 11.01.2019