Creating a c# windows service to poll a database

后端 未结 2 991
栀梦
栀梦 2021-01-31 05:15

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 thi

2条回答
  •  庸人自扰
    2021-01-31 06:08

    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.

提交回复
热议问题