在 Windows 服务中使用的最佳计时器 [英] Best Timer for using in a Windows service
问题描述
我需要创建一些 Windows 服务,每 N 段时间执行一次.
问题是:
我应该使用哪个定时器控件:System.Timers.Timer
还是 System.Threading.Timer
一个?它对某事有影响吗?
I need to create some windows service which will execute every N period of time.
The question is:
Which timer control should I use: System.Timers.Timer
or System.Threading.Timer
one? Does it influence on something?
我之所以这么问是因为我听到很多证据表明 System.Timers.Timer
在 Windows 服务中的工作不正确.
谢谢.
I am asking because I heard many evidences to non correct work of System.Timers.Timer
in windows services.
Thank you.
推荐答案
Both System.Timers.Timer
和 System.Threading.Timer
适用于服务.
Both System.Timers.Timer
and System.Threading.Timer
will work for services.
您想要避免的计时器是 System.Web.UI.Timer
和 System.Windows.Forms.Timer
,分别用于 ASP 应用程序和 WinForms.使用这些将导致服务加载一个额外的程序集,这对于您正在构建的应用程序类型来说并不是真正需要的.
The timers you want to avoid are System.Web.UI.Timer
and System.Windows.Forms.Timer
, which are respectively for ASP applications and WinForms. Using those will cause the service to load an additional assembly which is not really needed for the type of application you are building.
使用 System.Timers.Timer
像下面的例子(另外,确保你使用类级别的变量来防止垃圾收集,如 Tim Robinson 的回答中所述):
Use System.Timers.Timer
like the following example (also, make sure that you use a class level variable to prevent garbage collection, as stated in Tim Robinson's answer):
using System;
using System.Timers;
public class Timer1
{
private static System.Timers.Timer aTimer;
public static void Main()
{
// Normally, the timer is declared at the class level,
// so that it stays in scope as long as it is needed.
// If the timer is declared in a long-running method,
// KeepAlive must be used to prevent the JIT compiler
// from allowing aggressive garbage collection to occur
// before the method ends. (See end of method.)
//System.Timers.Timer aTimer;
// Create a timer with a ten second interval.
aTimer = new System.Timers.Timer(10000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer.Interval = 2000;
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program.");
Console.ReadLine();
// If the timer is declared in a long-running method, use
// KeepAlive to prevent garbage collection from occurring
// before the method ends.
//GC.KeepAlive(aTimer);
}
// Specify what you want to happen when the Elapsed event is
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}
}
/* This code example produces output similar to the following:
Press the Enter key to exit the program.
The Elapsed event was raised at 5/20/2007 8:42:27 PM
The Elapsed event was raised at 5/20/2007 8:42:29 PM
The Elapsed event was raised at 5/20/2007 8:42:31 PM
...
*/
如果您选择 System.Threading.Timer
,可以如下使用:
If you choose System.Threading.Timer
, you can use as follows:
using System;
using System.Threading;
class TimerExample
{
static void Main()
{
AutoResetEvent autoEvent = new AutoResetEvent(false);
StatusChecker statusChecker = new StatusChecker(10);
// Create the delegate that invokes methods for the timer.
TimerCallback timerDelegate =
new TimerCallback(statusChecker.CheckStatus);
// Create a timer that signals the delegate to invoke
// CheckStatus after one second, and every 1/4 second
// thereafter.
Console.WriteLine("{0} Creating timer.
",
DateTime.Now.ToString("h:mm:ss.fff"));
Timer stateTimer =
new Timer(timerDelegate, autoEvent, 1000, 250);
// When autoEvent signals, change the period to every
// 1/2 second.
autoEvent.WaitOne(5000, false);
stateTimer.Change(0, 500);
Console.WriteLine("
Changing period.
");
// When autoEvent signals the second time, dispose of
// the timer.
autoEvent.WaitOne(5000, false);
stateTimer.Dispose();
Console.WriteLine("
Destroying timer.");
}
}
class StatusChecker
{
int invokeCount, maxCount;
public StatusChecker(int count)
{
invokeCount = 0;
maxCount = count;
}
// This method is called by the timer delegate.
public void CheckStatus(Object stateInfo)
{
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
Console.WriteLine("{0} Checking status {1,2}.",
DateTime.Now.ToString("h:mm:ss.fff"),
(++invokeCount).ToString());
if(invokeCount == maxCount)
{
// Reset the counter and signal Main.
invokeCount = 0;
autoEvent.Set();
}
}
}
两个例子都来自 MSDN 页面.
Both examples comes from the MSDN pages.
这篇关于在 Windows 服务中使用的最佳计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!