0

我正在创建一个 Windows Server,它将自行安装在 dobleclick 上。但我正在编写核心代码。我面临的问题是

windows 服务器将从数据库中获取 10 条记录并使用 WCF 服务上传。现在完成这 10 条记录后,服务将再次查看数据库并再次获取 10 条记录。

但我也在使用定时器,这样这个过程将在每 5 分钟后继续。现在,如果在某个时间,使用 WCF 上传的时间超过 5 分钟,我必须停止新的执行并等待它完成。

我该怎么表现。

4

4 回答 4

3

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

于 2012-07-19T11:33:29.470 回答
1

这是锁定的理想方案。在下面的示例中,回调将每 5 分钟触发一次。如果在下一次回调触发时服务仍在处理前一批,它将简单地丢弃它并在 5 分钟内重试。如果您愿意,您可以更改它以使回调排队,但是,如果您排队太多,您需要警惕线程池饥饿。

您甚至可以将您的时间间隔缩短到 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); 
       } 
    } 
} 
于 2012-07-19T11:48:53.403 回答
0

当你开始做你的事情时,为什么不设置一个布尔值(或者锁定更好)。

在循环中,检查您的布尔(或锁定)是否处于活动状态,然后跳过,这样您的下一批将在 5 分钟后运行。

于 2012-07-19T11:34:05.897 回答
0

使用 a Timerto 计时五分钟,但告诉它不要重复:

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

FetchRecords这将在五分钟后调用该方法,但不重复 ( Timeout.Infinite)。

在您的FetchRecords方法结束时,重新启动计时器:

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

这将重新启动计时器。

只要方法调用在这段时间内完成,这种模式就可以让心跳每五分钟滴答一次,但如果方法调用仍在进行中,则不滴答。

于 2012-07-19T11:44:05.667 回答