Служба Windows, которая периодически работает

Assembla обеспечивает Wiki, билеты и другие вещи бесплатно, и позволяет интеграция GitHub . Если Вы не хотите использовать GitHub, можно использовать плоскость Мерзавец с Assembla (со всеми положительными героями, которых Вы получаете с любым другим проектом).

Оценка является дешевой, также (" 2$ на члена команды в месяц").

22
задан Josh 30 September 2009 в 14:32
поделиться

11 ответов

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

Вот статья, которая объясняет , как это сделать .

34
ответ дан 29 November 2019 в 03:28
поделиться

В моей компании мы полагаемся на планировщик задач Windows для запуска службы, а затем для ее завершения. Это гарантирует, что наша служба всегда будет работать в нужное время, а система планирования позволит сообщать об успехах / неудачах и т. Д.

1
ответ дан 29 November 2019 в 03:28
поделиться

Используйте для этого таймер.

1
ответ дан 29 November 2019 в 03:28
поделиться

You don't really want to use background worker. Background workers are used when you have something going one at the foreground (such as UI) and you also want something else to be done on the background. In your case there's no foreground processing, all you have is a single job that you need to run every once in a while.

Also, don't bother with the sleeping business etc. Instead, use a scheduler framework, such as Quartz.NET to wake it up every once in a while. This way when your service starts it will initialize the scheduler and do absolutely nothing until scheduler wakes up. When scheduler wakes up it will call a method of an object that you tell it to call when you initialize it.

This way the service will barely consume any CPU when idle and work full steam when needed.

2
ответ дан 29 November 2019 в 03:28
поделиться

Как насчет чего-то более похожего:

    public class LongRunningService : ServiceBase
{
    System.Threading.Thread processThread;
    System.Timers.Timer timer;
    private Boolean Cancel;

    protected override void OnStart(string[] args)
    {
        timer = new Timer(Settings.Default.SleepTimeHours * 3600000);
        timer.Elapsed += new ElapsedEventHandler(timer_Tick);
        timer.Start();

        Cancel = false;
    }

    protected override void OnContinue()
    {
        timer.Start();
    }

    protected override void OnPause()
    {
        timer.Stop();
    }

    protected override void OnStop()
    {
        if (processThread.ThreadState == System.Threading.ThreadState.Running)
        {
            Cancel = true;
            // Give thread a chance to stop
            processThread.Join(500);
            processThread.Abort();
        }
    }

    void timer_Tick(object sender, EventArgs e)
    {
        processThread = new System.Threading.Thread(new ThreadStart(DoWork));
        processThread.Start();
    }

    private void DoWork()
    {
        try
        {
            while (!Cancel)
            {

            if (Cancel) { return; }
            // Do General Work

            System.Threading.Thread.BeginCriticalRegion();
            {
                // Do work that should not be aborted in here.
            }
            System.Threading.Thread.EndCriticalRegion();
            }

        }
        catch (System.Threading.ThreadAbortException tae)
        {
            // Clean up correctly to leave program in stable state.
        }
    }
}
7
ответ дан 29 November 2019 в 03:28
поделиться

Consider a job scheduler like Quartz.Net.

http://quartznet.sourceforge.net/

10
ответ дан 29 November 2019 в 03:28
поделиться

This is not a very good idea, since you lock your thread for the full period of "SleepTimeHours" and you won't be able to even stop the service in the meantime.

You could either make this service so that it would sleep for e.g. 5 seconds and then check whether it's time to get back to work, and if not, sleep another 5 seconds (that would give you the necessary responsiveness, if you need to stop the service).

OR: you might be better off just writing a console app that can be scheduled using the Windows "scheduled tasks" feature in order to be run every x hours. That way, you won't be blocking or using any system resource if your app isn't doing anything......

Marc

15
ответ дан 29 November 2019 в 03:28
поделиться

Blog.StackOverflow.com has an interesting article on using cache expiration to handle periodic tasks:

http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/

2
ответ дан 29 November 2019 в 03:28
поделиться

У меня было такое же обсуждение с коллегами около часа назад! Я выбрал вариант while (_isPolling), потому что мне нужно, чтобы работа выполнялась синхронно. Я не хотел, чтобы та же работа выполнялась другим потоком (подход таймера), и реализация дополнительной блокировки для этого казалась пустой тратой.

1
ответ дан 29 November 2019 в 03:28
поделиться

Используйте подход, основанный на подходе System.Threading.WaitHandle.

using System.Threading;
private Thread _thread;
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
private ManualResetEvent _scheduleEvent = new ManualResetEvent(false);
private System.Timers.Timer _scheduleTimer = new System.Timers.Timer();
protected override void OnStart(string[] args)
{
    // Configure the timer.
    _scheduleTimer.AutoReset = false;
    _scheduleTimer.Interval = 120000; // 2 minutes in milliseconds
    _scheduleTimer.Elapsed += delegate { _scheduleEvent.Set(); }

    // Create the thread using anonymous method.
    _thread = new Thread( delegate() {
        // Create the WaitHandle array.
        WaitHandler[] handles = new WaitHandle[] {
            _shutdownEvent,
            _scheduleEvent
        };
        // Start the timer.
        _scheduleTimer.Start();
        // Wait for one of the events to occur.
        while (!_shutdownEvent.WaitOne(0)) {
            switch (WaitHandle.WaitAny(handles)) { 
               case 0:  // Shutdown Event
                   break;
               case 1:  // Schedule Event
                   _scheduleTimer.Stop();
                   _scheduleEvent.Reset();
                   ThreadPool.QueueUserWorkItem(PerformScheduledWork, null);
                   break;
               default:
                   _shutdownEvent.Set(); // should never occur
            }
        }
    } );
    _thread.IsBackground = true;
    _thread.Start();
}
protected override void OnStop()
{
    // Signal the thread to shutdown.
    _shutdownEvent.Set();
    // Give the thread 3 seconds to terminate.
    if (!_thread.Join(3000)) {
        _thread.Abort(); // not perferred, but the service is closing anyway
    }
}
private void PerformScheduledWork(object state)
{
    // Perform your work here, but be mindful of the _shutdownEvent in case
    // the service is shutting down.
    //
    // Reschedule the work to be performed.
     _scheduleTimer.Start();
}
5
ответ дан 29 November 2019 в 03:28
поделиться

У кого-то был аналогичный вопрос о суперпользователе. Вы можете установить инструмент, который отслеживает службы Windows. Что-то вроде Service Hawk поможет вам поддерживать работу служб или позволит вам запланировать автоматический перезапуск (возможно, в ночное время), чтобы служба работала без сбоев.

2
ответ дан 29 November 2019 в 03:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: