.net Windows服务中定时器的使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5495842/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use of Timer in Windows Service
提问by Parth Bhatt
I have a windows service where in I want to create a file every 10 seconds.
我有一个 Windows 服务,我想每 10 秒创建一个文件。
I got many reviews that Timer in Windows service would be the best option.
我收到很多评论,认为 Windows 服务中的计时器将是最佳选择。
How can I achieve this?
我怎样才能做到这一点?
回答by Jon Skeet
Firstly, pick the right kind of timer. You want either System.Timers.Timeror System.Threading.Timer- don't use one associated with a UI framework (e.g. System.Windows.Forms.Timeror DispatcherTimer).
首先,选择合适的定时器。您想要System.Timers.Timer或System.Threading.Timer- 不要使用与 UI 框架相关联的框架(例如System.Windows.Forms.Timer或DispatcherTimer)。
Timers are generally simple
定时器通常很简单
- set the tick interval
- Add a handler to the
Elapsedevent (or pass it a callback on construction), - Start the timer if necessary (different classes work differently)
- 设置滴答间隔
- 向
Elapsed事件添加处理程序(或在构造时传递回调), - 如有必要,启动计时器(不同的类工作方式不同)
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.
我在这个页面上有更多的信息,虽然我已经很长时间没有更新了。
回答by jgauffin
I would not recommend System.Timers.Timersince 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.
我不推荐,System.Timers.Timer因为它会默默地处理未处理的异常,因此隐藏了您应该修复的错误。恕我直言,如果您没有正确处理异常,您的代码会在您面前炸毁。
As for System.Threading.TimerI tend to use the Changemethod to start/stop the timer in a pattern like this:
至于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);
}
}
回答by iuppiter
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.
上面的代码是带有计时器的整个服务。我意识到这是一个旧帖子,但我花了几个小时才弄明白。希望它可以帮助那里的人。
回答by Marc Gravell
This should just be a case of firing up a System.Timers.Timerwith the right Interval(and AutoResetset to true), and handling Elapsed(but watch out; the callback is not on any particular thread).
这应该只是System.Timers.Timer使用正确的Interval(并AutoReset设置为 true)和处理Elapsed(但要注意;回调不在任何特定线程上)的情况。
MSDN has an example: http://msdn.microsoft.com/en-us/library/system.timers.timer.elapsed.aspx
MSDN 有一个例子:http: //msdn.microsoft.com/en-us/library/system.timers.timer.elapsed.aspx
also from MSDN:
也来自 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.
Timer 组件是一个基于服务器的计时器,它允许您指定在应用程序中引发 Elapsed 事件的重复间隔。然后您可以处理此事件以提供常规处理。例如,假设您有一个关键服务器,它必须每周 7 天、每天 24 小时保持运行。您可以创建一个使用 Timer 定期检查服务器并确保系统启动并运行的服务。如果系统没有响应,该服务可能会尝试重新启动服务器或通知管理员。
基于服务器的 Timer 设计用于多线程环境中的工作线程。服务器计时器可以在线程之间移动以处理引发的 Elapsed 事件,从而在按时引发事件方面比 Windows 计时器更准确。
回答by Pawe? Smejda
Here you have example how to use Timer in Windows Service.
这里有如何在 Windows Service 中使用Timer 的示例。
回答by Nuri YILMAZ
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; }
}
}

