在Windows服务中使用Timer

时间:2011-03-31 05:59:42

标签: .net windows-services service timer

我有一个Windows服务,我想在每10秒创建一个文件。

我得到很多评论,Windows服务中的Timer将是最佳选择。

我怎样才能做到这一点?

6 个答案:

答案 0 :(得分:31)

首先,选择合适的计时器。您想要System.Timers.TimerSystem.Threading.Timer - 请勿使用与UI框架相关联的内容(例如System.Windows.Forms.TimerDispatcherTimer)。

计时器通常很简单

  1. 设置滴答间隔
  2. Elapsed事件添加处理程序(或在构造时传递回调函数),
  3. 如有必要,启动计时器(不同类别的工作方式不同)
  4. 一切都会好的。

    样品:

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

    我有关于this page的更多信息,虽然我很长时间没有更新。

答案 1 :(得分:12)

我不推荐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);
    }

}

答案 2 :(得分:3)

这就是你如何做到这一点

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

上面的代码是带有计时器的整个服务。我意识到这是一个古老的帖子,但我需要花费数小时来解决这个问题。希望它可以帮助那里的人。

答案 3 :(得分:1)

这应该只是将System.Timers.TimerInterval(并AutoReset设置为true)并处理Elapsed(但要注意;回调不在任何特定线程上。)

MSDN有一个例子:http://msdn.microsoft.com/en-us/library/system.timers.timer.elapsed.aspx

也来自MSDN:

  

Timer组件是一个基于服务器的计时器,它允许您指定在应用程序中引发Elapsed事件的重复间隔。然后,您可以处理此事件以提供常规处理。例如,假设您有一台必须每周7天,每天24小时运行的关键服务器。您可以创建一个使用Timer定期检查服务器并确保系统已启动并运行的服务。如果系统没有响应,则服务可能会尝试重新启动服务器或通知管理员。

     

基于服务器的Timer设计用于多线程环境中的工作线程。服务器计时器可以在线程之间移动以处理引发的Elapsed事件,从而在准时引发事件时比Windows计时器更准确。

答案 4 :(得分:1)

这里有一些示例如何使用Timer in Windows Service

答案 5 :(得分:0)

经过全面测试的解决方案......

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