Skip to content

Instantly share code, notes, and snippets.

@sachinsu
Created April 23, 2020 06:52
Show Gist options
  • Save sachinsu/b2869d4f44fe14f439c6f0e60ea2b5d5 to your computer and use it in GitHub Desktop.
Save sachinsu/b2869d4f44fe14f439c6f0e60ea2b5d5 to your computer and use it in GitHub Desktop.
Windows Service using Topshelf with Cancellable Task
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Topshelf;
using NLog;
namespace ListenerService
{
class Program
{
static void Main(string[] args)
{
var rc = HostFactory.Run(x => //1
{
x.UseNLog();
x.Service<QueueListener>(s => //2
{
s.ConstructUsing(name => new QueueListener()); //3
s.WhenStarted(tc => tc.Start()); //4
s.WhenStopped(tc => tc.Stop()); //5
});
x.RunAsLocalSystem(); //6
x.SetDescription("Queue Listener Daemon"); //7
x.SetDisplayName("Tobeadded"); //8
x.SetServiceName("Tobeadded"); //9
x.OnException(ex =>
{
// Do something with the exception
});
}); //10
var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode()); //11
Environment.ExitCode = exitCode;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using NLog;
namespace ListenerService
{
class QueueListener
{
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
private readonly CancellationTokenSource tokenSource;
private readonly CancellationToken ct;
private Task processingTask;
public QueueListener()
{
this.tokenSource = new CancellationTokenSource();
ct = this.tokenSource.Token;
}
public void Start()
{
processingTask = Task.Run(async () =>
{
// Were we already canceled?
bool moreToDo = !ct.IsCancellationRequested;
Logger.Info("Processing Started !!");
try
{
while (moreToDo)
{
ct.ThrowIfCancellationRequested();
// todo: Add code to dequeue from Queue with timeout
await Task.Delay(100).ConfigureAwait(false);
if (ct.IsCancellationRequested)
{
Logger.Info("Stop Signal Received!!");
moreToDo = false;
}
}
} catch (OperationCanceledException ex)
{
Logger.Error(ex, "Cancellation Requested");
} finally
{
// Todo: cleanup
Logger.Info("Cleaning up");
}
}, ct); // Pass same token to Task.Run.
}
public void Stop()
{
Logger.Info("Stop Requested!!");
tokenSource.Cancel();
if (processingTask != null)
{
Task.WaitAll(processingTask);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment