最好使用Windows服务重复程序调用

我正在构建我的第一个Windows服务。 它是一个连接到邮箱并下载所有邮件并将其存储在本地驱动器上的组件。

我的问题是这些。

  1. 在c#windows服务中重复程序调用的最佳方法是什么。 我想用一个简单的计时器? 我在哪里开始和停止计时器? 它是在服务本身还是我的服务运行的程序?

  2. Windows服务中应包含哪些代码以用于以下function


protected override void OnStart(string[] args) { //timer? // MyProgram mp = new MyProgram(); } 

我应该只使用上面的新实例启动我的应用程序,还是应该包含更多内容?

正如我所说,这是我第一次使用Windows服务。

编辑:
感谢所有的答案。 当然有很多不同的方法可以做到这一点,但我发现对我来说最好的方法是作为解决方案的一个标记。

谢谢你的帮助!

这是一个模板,您可以使用它来处理使用计时器的重入问题。

 public partial class Service : ServiceBase{ System.Timers.Timer timer; public Service() { timer = new System.Timers.Timer(); //When autoreset is True there are reentrancy problme timer.AutoReset = false; timer.Elapsed += new System.Timers.ElapsedEventHandler(DoStuff); } protected override void OnStart(string[] args) { timer.Interval = 1; timer.Start(); } private void DoStuff(object sender, System.Timers.ElapsedEventArgs e) { Collection stuff = GetData(); LastChecked = DateTime.Now; foreach (Object item in stuff) { item.Dosomthing(); //Do somthing should only be called once } TimeSpan ts = DateTime.Now.Subtract(LastChecked); TimeSpan MaxWaitTime = TimeSpan.FromMinutes(5); if (MaxWaitTime.Subtract(ts).CompareTo(TimeSpan.Zero) > -1) timer.Interval = MaxWaitTime.Subtract(ts).Milliseconds; else timer.Interval = 1; timer.Start(); } 

OnContinue OnPause和OnStop很容易解决。

  protected override void OnPause() { base.OnPause(); this.timer.Stop(); } protected override void OnContinue() { base.OnContinue(); this.timer.Interval = 1; this.timer.Start(); } protected override void OnStop() { base.OnStop(); this.timer.Stop(); } 

我使用AutoResetEvent超时:

 while(!autoResetEvent.WaitOne(MY_MILLISECOND_WAIT)) { // do something } 

当我想要停止时,我只需设置autoResetEvent

定时器很糟糕,因为多个原因是Reentry

OnStart(string[] args)将创建autoResetEvent


这是我作为PollingWorker实现的:

 public class PollingWorker : IDisposable { private const int DEFAULT_INTERVAL_MS = 1000; // 1 second private const int WAIT_INTERVAL = 20; // MS private Thread _labourer = null; private int _pollingIntervalMS = DEFAULT_INTERVAL_MS; private ParameterizedThreadStart _work = null; private bool _working = false; private object _state = new object(); private AutoResetEvent _resetTimer = new AutoResetEvent(false); private bool _itsTimeToQuite = false; private bool _poked = false; private bool _isCurrentlyWorking = false; public string Name { get { return _labourer.Name; } set { _labourer.Name = value; } } public PollingWorker(int intervalMS, ParameterizedThreadStart work, object state): this(intervalMS, work, state, Guid.NewGuid().ToString()) { } public PollingWorker(int intervalMS, ParameterizedThreadStart work, object state, string name) { _pollingIntervalMS = intervalMS; _labourer = new Thread(new ThreadStart(TryDoingSomeWork)); _labourer.Name = name; _work = work; } public int PollingIntervalMS { get { return _pollingIntervalMS; } set { _pollingIntervalMS = value; } } public void StartWork() { StartWork(true); } public void StartWork(bool initialWait) { _working = true; _poked = !initialWait; _labourer.Start(); } public void PauseWork() { _working = false; } public void Quit() { Quit(int.MaxValue); } public void Quit(int maximumWaitToFinishCurrentWorkMS) { int totalWait = 0; _itsTimeToQuite = true; _working = false; _resetTimer.Set(); while (_isCurrentlyWorking && Thread.CurrentThread.Name != _labourer.Name) // in case Quit is called from Work { Thread.Sleep(WAIT_INTERVAL); totalWait += WAIT_INTERVAL; if(totalWait>maximumWaitToFinishCurrentWorkMS) break; } Dispose(); } // poke to wake up ! public void Poke() { try { // if you call set on the same thread while it is not on waitOne // it does not work if (Thread.CurrentThread.Name == this.Name) //_resetTimer.Set(); _poked = true; else _resetTimer.Set(); } catch { // ignore any error with poking } } private void TryDoingSomeWork() { while (!_itsTimeToQuite) { //Debug.WriteLine(string.Format("{0:ss fff}\t{1}\t{2}\t{3}", DateTime.Now, this.Name, string.Empty, string.Empty)); if (!_poked) _resetTimer.WaitOne(_pollingIntervalMS, false); _poked = false; // timed-out which means timer's pulse, so do some work if (_working) { _isCurrentlyWorking = true; _work(_state); _isCurrentlyWorking = false; } } } public object State { get { return _state; } set { lock (_state) { _state = value; } } } public bool Working { get { return _working; } } #region IDisposable Members public void Dispose() { try { _resetTimer.Close(); _labourer.Abort(); } catch { // dont want to raise errors now // so ignore especially threadabortexception!! } } #endregion } 

创建一个线程或其他东西,不需要计时器! 在OnStart中启动线程,在OnStop中可以停止线程。