Windows services 使用TPL在windows服务中运行轮询作业

Windows services 使用TPL在windows服务中运行轮询作业,windows-services,task-parallel-library,task,long-polling,Windows Services,Task Parallel Library,Task,Long Polling,在过去,我使用定时器进行轮询工作,从一个数据库检索数据,并在处理数据后插入另一个数据库。我试图用TPL任务并行库来写这个 下面是Task.Delay的代码,它是在带有TPL的窗口服务中运行轮询作业的有效方法吗 当我说“高效”时,它意味着它不会从操作系统中消耗更多的资源,也不会浪费资源。在此Wintellect视频中,强烈建议不要使用Thread.Sleep。他的论点是,如果一个应用程序没有使用线程,那么它就不应该持有线程,这样其他应用程序或同一个应用程序就可以从线程池中使用它 我假设任务。在内部

在过去,我使用定时器进行轮询工作,从一个数据库检索数据,并在处理数据后插入另一个数据库。我试图用TPL任务并行库来写这个

下面是Task.Delay的代码,它是在带有TPL的窗口服务中运行轮询作业的有效方法吗

当我说“高效”时,它意味着它不会从操作系统中消耗更多的资源,也不会浪费资源。在此Wintellect视频中,强烈建议不要使用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
        }
    }
}

是的,你的代码看起来不错

此作业必须每分钟运行一次,应避免重叠

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

按照目前的结构,它在执行之间有一分钟的延迟,这与每分钟运行并不完全相同。如果这对你来说足够好,我会保持原样。

不要用延迟代替计时器。将长时间运行的任务标记为长时间运行您的意思是,使用计时器而不是延迟吗?是的,不要对此类任务使用延迟扫描您请解释原因?延迟是一项任务,不能保证每分钟都准确启动,它可能会延迟一段时间,特别是如果有许多其他任务。您应该使用Threading.Timer,它适用于这种情况。另外,把你的任务标记为long runningI我对我所说的效率添加了一些评论。非常感谢您的反馈。