2017-04-05 58 views
-1

过去,我使用计时器来执行轮询作业,该作业从一个数据库检索数据并在处理完数据后插入另一个数据库。我试图用TPL(任务并行库)编写此代码。使用TPL在Windows服务中运行轮询作业

是与Task.Delay下面的代码,高效地运行在窗口服务与TPL轮询的工作吗?

当我说'高效'时,这意味着它不会从操作系统消耗更多资源,也不会浪费。 Jeffrey Ritcher在此Wintellect视频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 
     } 
    } 
} 
+1

请勿使用'Delay'而不是'Timer'。将长时间运行的任务标记为“LongRunning” – VMAtm

+0

您的意思是使用'''Timer'而不是''''Delay'''? –

+1

是的,不要使用'延迟'这样的任务 – VMAtm

回答

1

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

这项工作必须每分钟运行一次,应避免重叠。

它目前的结构方式,它具有执行之间的分钟延迟的,这是不完全一样的东西“跑每一分钟”。如果这对你来说够好的话,我会保持原样。

+0

我添加了一些意见,我的意思是效率。感谢您的反馈。 –

+0

'Task.Delay'不使用'Thread.Sleep'。它使用一个计时器。 –