我有一个Windows服务,在其中我希望每10秒钟创建一个文件。
我收到很多评论说,Windows服务中的定时器是最好的选择。
我该如何实现这一点?
我有一个Windows服务,在其中我希望每10秒钟创建一个文件。
我收到很多评论说,Windows服务中的定时器是最好的选择。
我该如何实现这一点?
首先,选择正确类型的定时器。你需要使用 System.Timers.Timer
或System.Threading.Timer
- 不要使用与UI框架相关的定时器(例如System.Windows.Forms.Timer
或DispatcherTimer
)。
通常来说,定时器是非常简单的:
Elapsed
事件添加处理程序(或在构造函数中传递回调函数)这样就可以了。
示例:
// 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...");
}
}
我在这个页面上有更多信息,尽管我已经很长时间没有更新了。
Thread.Sleep(10000)
吗? - Parth Bhatt我不建议使用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);
}
}
object state
参数。 - jgauffinprotected void MyWorkerMethod(object state)
- jgauffin这是简单的操作步骤
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()
{
}
}
}
上面的代码是整个带有计时器的服务。我意识到这是一篇旧文章,但我花了几个小时才搞明白。希望能帮助到某个需要的人。
完全测试过的解决方案...
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; }
}
}