我有一个Windows服务,我想在每10秒创建一个文件。
我得到很多评论,Windows服务中的Timer将是最佳选择。
我怎样才能做到这一点?
答案 0 :(得分:31)
首先,选择合适的计时器。您想要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...");
}
}
我有关于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.Timer
与Interval
(并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; }
}
}