运行 使用 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" 不太一样。如果这对你来说足够好,我会保持原样。
过去我用定时器做轮询工作,从一个数据库检索数据并在处理数据后插入另一个数据库。我正在尝试使用 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" 不太一样。如果这对你来说足够好,我会保持原样。