Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Topshelf - handling loops

Tags:

c#

loops

topshelf

Generally with services, the task you want to complete is repeated, maybe in a loop or maybe a trigger or maybe something else.

I'm using Topshelf to complete a repeated task for me, specifically I'm using the Shelf'ing functionality.

The problem I'm having is how to handle the looping of the task.

When boot strapping the service in Topshelf, you pass it a class (in this case ScheduleQueueService) and indicate which is its Start method and it's Stop method:

Example:

    public class QueueBootstrapper : Bootstrapper<ScheduledQueueService>
{
    public void InitializeHostedService(IServiceConfigurator<ScheduledQueueService> cfg)
    {
        cfg.HowToBuildService(n => new ScheduledQueueService());
        cfg.SetServiceName("ScheduledQueueHandler");
        cfg.WhenStarted(s => s.StartService());
        cfg.WhenStopped(s => s.StopService());
    }
}

But in my StartService() method I am using a while loop to repeat the task I'm running, but when I attempt to stop the service through Windows services it fails to stop and I suspect its because the StartService() method never ended when it was originally called.

Example:

 public class ScheduledQueueService
{
    bool QueueRunning;

    public ScheduledQueueService()
    {
      QueueRunning = false;
     }


    public void StartService()
    {
        QueueRunning = true;

        while(QueueRunning){
                     //do some work
         }
    }

  public void StopService()     
  {
         QueueRunning = false;
  }
}

what is a better way of doing this?

  1. I've considered using the .NET System.Threading.Tasks to run the work in and then maybe closing the thread on StopService()

  2. Maybe using Quartz to repeat the task and then remove it.

Thoughts?

like image 912
Mike Avatar asked Dec 21 '11 09:12

Mike


2 Answers

Generally, how I would handle this is have a Timer event, that fires off a few moments after StartService() is called. At the end of the event, I would check for a stop flag (set in StopService()), if the flag (e.g. your QueueRunning) isn't there, then I would register a single event on the Timer to happen again in a few moments.

We do something pretty similar in Topshelf itself, when polling the file system: https://github.com/Topshelf/Topshelf/blob/v2_master/src/Topshelf/FileSystem/PollingFileSystemEventProducer.cs#L80

Now that uses the internal scheduler type instead of a Timer object, but generally it's the same thing. The fiber is basically which thread to process the event on.

If you have future questions, you are also welcomed to join the Topshelf mailing list. We try to be pretty responsive on there. http://groups.google.com/group/topshelf-discuss

like image 125
Travis Avatar answered Oct 08 '22 18:10

Travis


I was working on some similar code today I stumbled on https://stackoverflow.com/a/2033431/981 by accident and its been working like a charm for me.

like image 30
David Negron Avatar answered Oct 08 '22 19:10

David Negron