创建一个C#窗口服务轮询数据库 [英] Creating a c# windows service to poll a database

查看:582
本文介绍了创建一个C#窗口服务轮询数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个民意调查数据库,并执行取决于数据的操作被带回的服务。



我不知道什么是最好的方法这样做的,我能找到关于它的几个博客和这个堆栈溢出问题轮询服务 - C#。不过我持谨慎态度,他们都是很旧的和可能已经过时了。



谁能告诉我对目前的建议或最佳实践(如果有的话)上做像这样或点我在近期的博客文章这个方向。从我可以收集或者使用定时器或TPL任务是这样做的两种可能方式。



如果计时器仍然建议那么他们将如何在该服务被停止工作因为我打算对这些服务做可能需要30分钟的操作,这就是为什么我说使用任务,因为我可以使用任务取消标记但这些异常抛出时取消(纠正我,如果我错了)和我不ŧ以为我真的希望这样的行为(虽然纠正我,如果你觉得还有一个原因,我会希望这样)。



对不起,我可能会问了很多在一个单一的问题,但我不能完全肯定自己是什么我问。


< DIV CLASS =h2_lin>解决方案

去同一个Windows服务这一点。使用计划任务不是一个坏主意本身,而是因为你说的民意调查可以每隔2分钟会发生,那么你可能会更好的服务去。该服务将允许您轮询之间保持状态,并且您将有超过投票的时间更多的控制为好。你说一旦拉开序幕,所以也许你会希望推迟投票,直到操作完成该操作可能需要30多分钟。这是一个容易一点,当逻辑运行作为一种服务的事情。



在结束它并没有真正不管你用什么机制来生成投票。你可以使用一个定时器或休眠的专用线程/任务或什么的。就个人而言,我觉得专门的线程/任务,更易于使用比这些事情,因为它是比较容易控制的轮询间隔计时器。此外,你一定要使用提供第三方物流合作取消机制。它没有必要抛出异常。它只做因此,如果调用 ThrowIfCancellationRequested 。您可以使用 IsCancellationRequested ,而不是只检查取消标记的状态。



下面是您可以使用一个非常通用的模板。上手

 公共类YourService:ServiceBase 
{
私人CancellationTokenSource CTS =新CancellationTokenSource() ;
私人任务MainTask的= NULL;

保护覆盖无效的OnStart(字串[] args)
{
MainTask的=新的任务(投票,cts.Token,TaskCreationOptions.LongRunning);
mainTask.Start();
}

保护覆盖无效调用OnStop()
{
cts.Cancel();
mainTask.Wait();
}

私人无效投票()
{
的CancellationToken取消= cts.Token;
时间跨度间隔= TimeSpan.Zero;
,而(!cancellation.WaitHandle.WaitOne(间隔))
{

{
//把你的代码在这里查询。
//偶尔检查取消状态。
如果(cancellation.IsCancellationRequested)
{
中断;
}
间隔= WaitAfterSuccessInterval;
}
赶上(例外捕获)
{
//记录异常。
间隔= WaitAfterErrorInterval;
}
}
}
}



像我说,我通常使用一个专用的线程/任务,而不是一个计时器。我这样做是因为我的轮询间隔是几乎从来不变。下来,如果检测到暂时的错误(如网络或服务器可用性问题),这样我的日志文件不具有相同的错误消息快速连续遍地填写再次我通常开始放缓投票。


I am wanting to write a service that polls a database and performs an operation depending on the data being brought back.

I am not sure what is the best way of doing this, I can find a few blogs about it and this stack overflow question Polling Service - C#. However I am wary that they are all quite old and possibly out of date.

Can anyone advise me on the current advice or best practices (if there are any) on doing something like this or point me in the direction of a more recent blog post about this. From what I can gather either using a timer or tpl tasks are two potential ways of doing this.

If timers are still suggested then how will they work when the service is stopped because the operations I intend for these services to do could potentially take 30+ minutes, this is why I say use tasks because I can use a task cancellation token but these throw exceptions when cancelled (correct me if I am wrong) and I don't think I really want that behaviour (although correct me if you think there is a reason I will want that).

Sorry that I may be asking quite a lot in a single question but I'm not entirely sure myself what I am asking.

解决方案

Go with a Windows service for this. Using a scheduled task is not a bad idea per se, but since you said the polls can occur every 2 minutes then you are probably better off going with the service. The service will allow you to maintain state between polls and you would have more control over the timing of the polls as well. You said the operation might take 30+ minutes once it is kicked off so maybe you would want to defer polls until the operation complete. That is a bit easier to do when the logic is ran as a service.

In the end it does not really matter what mechanism you use to generate the polls. You could use a timer or a dedicated thread/task that sleeps or whatever. Personally, I find the dedicated thread/task easier to work with than a timer for these kinds of things because it is easier to control the polling interval. Also, you should definitely use the cooperative cancellation mechanism provided with the TPL. It does not necessary throw exceptions. It only does so if you call ThrowIfCancellationRequested. You can use IsCancellationRequested instead to just check the cancellation token's state.

Here is a very generic template you might use to get started.

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;
      }
    }
  }
}

Like I said, I normally use a dedicated thread/task instead of a timer. I do this because my polling interval is almost never constant. I usually start slowing the polls down if a transient error is detected (like network or server availability issues) that way my log file does not fill up with the same error message over and over again in rapid succession.

这篇关于创建一个C#窗口服务轮询数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆