创建ac#windows服务以轮询数据库

use*_*347 18 c# windows service multithreading timer

我想编写一个服务来轮询数据库并根据被带回的数据执行操作.

我不确定这样做的最佳方式是什么,我可以找到一些关于它的博客和这个堆栈溢出问题轮询服务 - C#.但是我很谨慎他们都很老了,可能已经过时了.

任何人都可以告诉我目前的建议或最佳实践(如果有的话)做这样的事情或指向我最近的博客文章的方向.从我可以使用计时器或tpl任务收集的是两种可能的方法.

如果仍然建议定时器,那么当服务停止时它们将如何工作,因为我打算让这些服务执行的操作可能需要30多分钟,这就是为什么我说使用任务因为我可以使用任务取消令牌但这些抛出取消时的异常(如果我错了,请纠正我)并且我不认为我真的想要那种行为(尽管如果你认为我有理由我会这样做,请纠正我).

对不起,我在一个问题上可能会问很多,但我不能完全确定自己在问什么.

Bri*_*eon 29

为此,请使用Windows服务.使用计划任务本身并不是一个坏主意,但由于您说每两分钟可以进行一次民意调查,因此您可能最好使用该服务.该服务将允许您维持民意调查之间的状态,您也可以更好地控制民意调查的时间.你说这个操作一旦开始就可能需要30多分钟,所以你可能希望推迟民意调查直到操作完成.当逻辑作为服务运行时,这样做更容易一些.

最后,用于生成民意调查的机制并不重要.您可以使用计时器或睡眠的专用线程/任务.就个人而言,我发现专用线程/任务比这些事情的计时器更容易使用,因为它更容易控制轮询间隔.此外,您绝对应该使用TPL提供的合作取消机制.它没有必要抛出异常.只有你打电话才会这样做ThrowIfCancellationRequested.您可以使用它IsCancellationRequested来检查取消令牌的状态.

这是一个非常通用的模板,您可以使用它来开始.

public class YourService : ServiceBase
{
  private CancellationTokenSource cts = new CancellationTokenSource();
  private Task mainTask = null;

  protected override void OnStart(string[] args)
  {
    mainTask = new Task(Poll, cts.Token, TaskCreationOptions.LongRunning);
    mainTask.Start();
  }

  protected override void OnStop()
  {
    cts.Cancel();
    mainTask.Wait();
  }

  private void Poll()
  {
    CancellationToken cancellation = cts.Token;
    TimeSpan interval = TimeSpan.Zero;
    while (!cancellation.WaitHandle.WaitOne(interval))
    {
      try 
      {
        // Put your code to poll here.
        // Occasionally check the cancellation state.
        if (cancellation.IsCancellationRequested)
        {
          break;
        }
        interval = WaitAfterSuccessInterval;
      }
      catch (Exception caught)
      {
        // Log the exception.
        interval = WaitAfterErrorInterval;
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

就像我说的,我通常使用专用线程/任务而不是计时器.我这样做是因为我的轮询时间间隔几乎不变.如果检测到瞬态错误(如网络或服务器可用性问题),我通常会开始减慢轮询速度,因为我的日志文件不能快速连续地反复填充相同的错误消息.