Использование таймера в службе Windows - PullRequest
19 голосов
/ 31 марта 2011

У меня есть служба Windows, в которой я хочу создавать файл каждые 10 секунд.

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

Как я могудостичь этого?

Ответы [ 6 ]

31 голосов
/ 31 марта 2011

Во-первых, выберите правильный тип таймера.Вы хотите либо System.Timers.Timer, либо System.Threading.Timer - не используйте тот, который связан с инфраструктурой пользовательского интерфейса (например, System.Windows.Forms.Timer или DispatcherTimer).

Таймеры, как правило, простые

  1. установить интервал между галочками
  2. Добавить обработчик к событию Elapsed (или передать ему обратный вызов при построении),
  3. При необходимости запустить таймер (разные классы работают по-разному)

и все будет хорошо.

Образцы:

// System.Threading.Timer sample
using System;
using System.Threading;

class Test
{
    static void Main() 
    {
        TimerCallback callback = PerformTimerOperation;
        Timer timer = new Timer(callback);
        timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(1));
        // Let the timer run for 10 seconds before the main
        // thread exits and the process terminates
        Thread.Sleep(10000);
    }

    static void PerformTimerOperation(object state)
    {
        Console.WriteLine("Timer ticked...");
    }
}

// System.Timers.Timer example
using System;
using System.Threading;
using System.Timers;
// Disambiguate the meaning of "Timer"
using Timer = System.Timers.Timer;

class Test
{
    static void Main() 
    {
        Timer timer = new Timer();
        timer.Elapsed += PerformTimerOperation;
        timer.Interval = TimeSpan.FromSeconds(1).TotalMilliseconds;
        timer.Start();
        // Let the timer run for 10 seconds before the main
        // thread exits and the process terminates
        Thread.Sleep(10000);
    }

    static void PerformTimerOperation(object sender,
                                      ElapsedEventArgs e)
    {
        Console.WriteLine("Timer ticked...");
    }
}

У меня есть немного больше информации о этой странице , хотя я давно не обновлял ее.

12 голосов
/ 31 марта 2011

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

Что касается System.Threading.Timer Я склонен использовать метод Change для запуска / остановки таймера в схеме, подобной этой:

public class MyCoolService
{
    Timer _timer;

    public MyCoolService()
    {
        _timer = new Timer(MyWorkerMethod, Timeout.Infinite, Timeout.Infinite);
    }

    protected void OnStart()
    {
        _timer.Change(15000, Timeout.Infinte);
    }

    protected void MyWorkerMethod()
    {
        //pause timer during processing so it
        // wont be run twice if the processing takes longer
        // than the interval for some reason
        _timer.Change(Timeout.Infinite, Timeout.Infinite); 

        try
        {
            DoSomeWork();
        }
        catch (Exception err)
        {
            // report the error to your manager if you dare
        }

        // launch again in 15 seconds
        _timer.Change(15000, Timeout.Infinite);
    }

}
3 голосов
/ 08 января 2013

Вот как вы это делаете просто

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;
using System.IO;

  namespace MyService
{
    public partial class Service1 : ServiceBase
    {
        Timer myTimer;
        int x = 0;
        public Service1()
         {
             InitializeComponent();
         }

         protected override void OnStart(string[] args)
         {

             myTimer = new Timer(10000);                                // Sets a 10 second interval
             myTimer.Elapsed +=new ElapsedEventHandler(myTimer_Elapsed);// Specifies The Event Handler
             myTimer.Enabled = true;                                    // Enables the control
             myTimer.AutoReset = true;                                  // makes it repeat
             myTimer.Start();                                           // Starts the interval




         }
         protected void myTimer_Elapsed(object sender, ElapsedEventArgs e)
         {
             // All the Cool code that you need to run eg. Making a new file every 10 seconds
             x++;
             StreamWriter myFile = new StreamWriter("MyFile" + x.ToString() + ".txt");
             myFile.Write("Something");
             myFile.Close();
         }
         protected override void OnStop()
         {
         }
     }
 }

Код выше - это весь сервис с таймером. Я понимаю, что это старый пост, но мне понадобились часы, чтобы понять это. Надеюсь, это кому-нибудь поможет.

1 голос
/ 31 марта 2011

Вот пример использования Таймер в Windows Service .

1 голос
/ 31 марта 2011

Это просто случай запуска System.Timers.Timer с правым IntervalAutoReset установленным в true) и обработки Elapsed (но будьте внимательны; обратный вызов не связан с каким-либо конкретным потоком ).

MSDN имеет пример: http://msdn.microsoft.com/en-us/library/system.timers.timer.elapsed.aspx

также из MSDN:

Компонент Timer - это серверный таймер, который позволяет вам указать повторяющийся интервал, с которым событие Elapsed вызывается в вашем приложении. Затем вы можете обработать это событие, чтобы обеспечить регулярную обработку. Например, предположим, что у вас есть критически важный сервер, который должен работать 24 часа в сутки 7 дней в неделю Вы можете создать службу, которая использует таймер для периодической проверки сервера и проверки работоспособности системы. Если система не отвечает, служба может попытаться перезапустить сервер или уведомить администратора.

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

0 голосов
/ 02 января 2015

полностью протестированное решение ...

 using System;
    using System.Configuration;
    using System.ServiceProcess;
    using System.Timers;

    namespace SomeServices.WindowsService
    {
        public partial class SomeServicesWindowsService : ServiceBase 
        {
            private const int DefaultTriggerInterval = 5000;

            private readonly Timer _trigger;

            public SomeServicesWindowsService ()
            {
                InitializeComponent();
                _trigger = new Timer(GetTriggerInterval());
                _trigger.Elapsed += TriggerElapsed;
            }
            public bool ContinueTriggering { get; set; }

            public void TriggerElapsed(object sender, ElapsedEventArgs e)
            {
                var subject = (Timer)sender;
                subject.Stop();

                using (var service = new DeliveryServiceManager())
                {
                    service.ShouldContinue += service_ShouldContinue;
                    service.Run();
                }

                if (ContinueTriggering)
                    subject.Start();
            }

            void service_ShouldContinue(object sender, ShouldContinueEventArgs e)
            {
                e.Continue = ContinueTriggering;
            }

            public double GetTriggerInterval()
            {
                int interval;
                return int.TryParse(ConfigurationManager.AppSettings["triggerInterval"], out interval)
                    ? interval
                    : DefaultTriggerInterval;
            }

            protected override void OnStart(string[] args)
            {
                ContinueTriggering = true;
                _trigger.Start();
            }

            protected override void OnStop()
            {
                ContinueTriggering = false;
                _trigger.Stop();
            }
        }

        public class DeliveryServiceManager : IDisposable
        {
            public event EventHandler<ShouldContinueEventArgs> ShouldContinue;
            protected virtual void OnShouldContinue(ShouldContinueEventArgs e)
            {
                var handler = ShouldContinue;
                if (handler != null)
                {
                    handler(this, e);
                }
            }

            public void Dispose()
            {
                ShouldContinue = null;
            }

            public void Run()
            {
               //Iterate Something here.
                var eventArgs = new ShouldContinueEventArgs{Continue =  false};
                OnShouldContinue(eventArgs);
                if (!eventArgs.Continue)
                {
                    //Run step();        
                }
            }
        }

        public class ShouldContinueEventArgs : EventArgs
        {
            public bool Continue { get; set; }
        }
    }
...