运行 使用 TPL 的 windows 服务中的轮询作业

Running a polling job in a windows service with TPL

过去我用定时器做轮询工作,从一个数据库检索数据并在处理数据后插入另一个数据库。我正在尝试使用 TPL(任务并行库)来编写此代码。

以下带有 Task.Delay 的代码是否是 运行 在带有 TPL 的 window 服务 中轮询作业的有效方式?

当我说 'efficient' 时,这意味着它不会从 OS 中消耗更多资源,也不会浪费。 Jeffrey Ritcher in this Wintellect video on Thread Fundamentals 强烈反对使用 Thread.Sleep。他的论点是,如果一个应用程序不使用线程,那么它不应该持有一个线程,这样其他应用程序或同一个应用程序就可以从线程池中使用它。

我假设 Task.Delay 在内部做一个 Thread Sleep 所以我认为它是低效的。

另一个要求是这项工作也必须每分钟运行并且应该避免重叠。

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
        }
    }
}

是的,您的代码看起来不错。

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

它目前的结构方式,在执行之间有 分钟的延迟 ,这与 "running every minute" 不太一样。如果这对你来说足够好,我会保持原样。