Search code examples
windows-servicestask-parallel-librarytasklong-polling

Running a polling job in a windows service with TPL


In the past I have used timer to do polling job that retrieves the data from one database and insert into another after processing the data. I'm trying to write this with TPL (Task Parallel Library).

Is the following code with Task.Delay, the efficient way to run a polling job in a window service with TPL?

When I said 'efficient' it means it doesn't consume more resources from the OS neither wasting. Jeffrey Ritcher in this Wintellect video on Thread Fundamentals strongly discourages to use Thread.Sleep. His argument is that an app should not hold a thread if it is not using so other apps or the same app can use it from the thread pool.

I assume Task.Delay internally doing a Thread Sleep so I assume it is inefficient.

Another requirement is that this job also has to run every minute and overlapping should be avoided.

class Program
{
    private CancellationTokenSource _cancellationTokenSource;
    private Task _etlTask;

    protected override void OnStart(string[] args)
    {
        _cancellationTokenSource = new CancellationTokenSource();

        _etlTask = Task.Run(
            async () =>
                    {
                        CancellationToken token = tokenSource.Token;

                        while (!token.IsCancellationRequested)
                        {
                            await etlJob.Run(); // An ETL Job to read from DB to update another DB

                            await Task.Delay(TimeSpan.FromMinutes(1), token);
                        }
                    });
    }

    protected override void OnStop()
    {
        _cancellationTokenSource.Cancel();

        try
        {
            _etlTask.Wait();
        }
        catch (Exception e)
        {
            // handle exeption
        }
    }
}

Solution

  • Yes, your code looks fine.

    This job has to run every minute and overlapping should be avoided.

    The way it's currently structured, it has a minute of delay between executions, which is not quite the same thing as "running every minute". If that's good enough for you, I'd just keep it as-is.