开发者

Use of Timer in Windows Service

开发者 https://www.devze.com 2023-02-20 18:16 出处:网络
I have a windows service where in I want to creat开发者_如何学运维e a file every 10 seconds. I got many reviews that Timer in Windows service would be the best option.

I have a windows service where in I want to creat开发者_如何学运维e a file every 10 seconds.

I got many reviews that Timer in Windows service would be the best option.

How can I achieve this?


Firstly, pick the right kind of timer. You want either System.Timers.Timer or System.Threading.Timer - don't use one associated with a UI framework (e.g. System.Windows.Forms.Timer or DispatcherTimer).

Timers are generally simple

  1. set the tick interval
  2. Add a handler to the Elapsed event (or pass it a callback on construction),
  3. Start the timer if necessary (different classes work differently)

and all will be well.

Samples:

// 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...");
    }
}

I have a bit more information on this page, although I haven't updated that for a long time.


I would not recommend System.Timers.Timer since it silently eats unhandled exceptions and therefore hides errors that you should fix. imho better that your code blows up in your face if you do not handle exceptions properly.

As for System.Threading.Timer I tend to use the Change method to start/stop the timer in a pattern like this:

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);
    }

}


This is how you do it simply

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()
         {
         }
     }
 }

The Code above is the whole service with the timer. I realize this is an old post but it took me hours to figure this out. Hopefully it helps someone out there.


This should just be a case of firing up a System.Timers.Timer with the right Interval (and AutoReset set to true), and handling Elapsed (but watch out; the callback is not on any particular thread).

MSDN has an example: http://msdn.microsoft.com/en-us/library/system.timers.timer.elapsed.aspx

also from MSDN:

The Timer component is a server-based timer, which allows you to specify a recurring interval at which the Elapsed event is raised in your application. You can then handle this event to provide regular processing. For example, suppose you have a critical server that must be kept running 24 hours a day, 7 days a week. You could create a service that uses a Timer to periodically check the server and ensure that the system is up and running. If the system is not responding, the service could attempt to restart the server or notify an administrator.

The server-based Timer is designed for use with worker threads in a multithreaded environment. Server timers can move among threads to handle the raised Elapsed event, resulting in more accuracy than Windows timers in raising the event on time.


Here you have example how to use Timer in Windows Service.


fully tested solution...

 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; }
        }
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号