简体   繁体   English

使用Scheduler创建Windows服务?

[英]Creating Windows Service with Scheduler?

I am creating a Windows Server which will install itself on dobleclick. 我正在创建Windows Server,它将自己安装在dobleclick上。 But i am writing the core code. 但是我正在编写核心代码。 The problem i am facing is 我面临的问题是

The windows Server will fetch 10 records from database and upload using a WCF Service. Windows Server将从数据库中获取10条记录,并使用WCF服务上载。 Now after the completing of these 10 records, the service will again look into database and take again 10 records. 现在,完成这10条记录后,该服务将再次查看数据库并再次获取10条记录。

But i am also using Timer so that this process will continue every after 5 minutes. 但是我也使用Timer,以便此过程每隔5分钟就会继续。 Now if at certain time, this upload using WCF took more than 5 Minutes, i have to stop the new execution and wait until it is complete. 现在,如果在某些时候,使用WCF进行的上传花费了超过5分钟的时间,我必须停止新的执行并等待它完成。

How can i perform. 我该如何执行。

每次计时器计时时,将其禁用,并在执行结束时再次启用它,这样它将在最后一次执行结束后5分钟再次计时。

This is an ideal scenario for locking. 这是锁定的理想方案。 In the below example the callback will trigger every 5 minutes. 在下面的示例中,回调将每5分钟触发一次。 If the service is still processing a previous batch when the next callback triggers it will simply discard it and try again in 5 minutes time. 如果服务在下一次回调触发时仍在处理前一个批处理,它将简单地将其丢弃并在5分钟后重试。 You can change this to have the callbacks queue up if you prefer, however, you would need to be wary of thread pool starvation if you queue too many. 您可以根据需要更改此设置以使回调排队,但是,如果排队过多,则需要警惕线程池不足。

You could even reduce your interval to say 1 minute to avoid any long delays in the scenario where a batch runs over. 您甚至可以将间隔缩短为1分钟,以避免在批处理结束的情况下出现任何长时间的延迟。

static Timer timer; 
static object locker = new object(); 

public void Start() 
{ 
    var callback = new TimerCallback(DoSomething); 
    timer = new Timer(callback, null, 0, 300000); 
} 

public void DoSomething() 
{ 
    if (Monitor.TryEnter(locker)) 
    { 
       try 
       { 
           // my processing code 
       } 
       finally 
       { 
           Monitor.Exit(locker); 
       } 
    } 
} 

Why not just set a boolean (or lock even better) when you start doing your thing. 开始做事情时,为什么不只设置一个布尔值(甚至更好地锁定)。

In the loop, check if you boolean (or lock) is active and then skip, so your next batch will run in another 5 minutes. 在循环中,检查布尔(或锁)是否处于活动状态,然后跳过,这样下一批将在另外5分钟内运行。

Use a Timer to time five minutes, but tell it not to repeat: 使用Timer计时五分钟,但不要重复:

timer = new Timer(state => FetchRecords(), null, 
                    new TimeSpan(0, 5, 0), Timeout.Infinite);

This will call the FetchRecords method after five minutes has elapsed, but with not repetition ( Timeout.Infinite ). 五分钟后,这将调用FetchRecords方法,但不会重复( Timeout.Infinite )。

At the end of your FetchRecords method, restart the timer: FetchRecords方法的末尾,重新启动计时器:

timer.Change(new TimeSpan(0, 5, 0), Timeout.Infinite);

This will start the timer going again. 这将启动计时器再次运行。

This pattern allows you to have the heartbeat ticking every five minutes so long as the method calls completes within this time, but to not tick if the method call is still in progress. 只要该方法调用在此时间内完成,此模式就可以使心跳每5分钟滴答一次,但如果方法调用仍在进行中,则不会滴答。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM