Search code examples
c#asynchronoustasktopshelf

Topshelf start stuck in infinite loop


I'm creating a message processor to take messages of a queue

I have used topshelf for this and justgot some basic code for now. However my message processor is stuck in a loop and causing my topshelf service to not start. I thought if I returned and stored the task, this would not be the case

class Program
{
    static void Main(string[] args)
    {
        HostFactory.Run(configure =>
        {
            configure.Service<WorkerService>(service =>
            {
                service.ConstructUsing(() => new WorkerService());
                service.WhenStarted(s => s.Start());
                service.WhenStopped(s => s.Stop());
            });

            configure.RunAsLocalSystem();
        });
    }
}

public class WorkerService
{
    private Task _task;
    private Processor _processor;
    private readonly CancellationTokenSource _cancellation;

    public WorkerService()
    {
        _cancellation = new CancellationTokenSource();
        _processor = new Processor();
    }

    public void Start()
    {
        Console.WriteLine("Starting");
        _task = _processor.Run(_cancellation.Token);
        Console.WriteLine("I NEVER GET HERE");
    }

    public void Stop()
    {
        _cancellation.Cancel();
        _task.Wait();
    }
}

public class Processor
{
    public async Task Run(CancellationToken cancellationToken)
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            Console.WriteLine("Running");
        }
    }
}

So when I look at my windows services I just see this app stuck in "Starting"


Solution

  • Your run function doesn't actually hit an await call (where it will exit and later resume). In fact, it doesn't exit at all. You're stuck in the Run method. Try putting this after your Console.WriteLine:

    await Task.Delay(200);
    

    In addition, you might consider not mixing async/await with traditional Task.Wait(), as that's known to cause deadlocks as well. Example: await vs Task.Wait - Deadlock?