我正在创建一个 Windows Server,它将自行安装在 dobleclick 上。但我正在编写核心代码。我面临的问题是
windows 服务器将从数据库中获取 10 条记录并使用 WCF 服务上传。现在完成这 10 条记录后,服务将再次查看数据库并再次获取 10 条记录。
但我也在使用定时器,这样这个过程将在每 5 分钟后继续。现在,如果在某个时间,使用 WCF 上传的时间超过 5 分钟,我必须停止新的执行并等待它完成。
我该怎么表现。
我正在创建一个 Windows Server,它将自行安装在 dobleclick 上。但我正在编写核心代码。我面临的问题是
windows 服务器将从数据库中获取 10 条记录并使用 WCF 服务上传。现在完成这 10 条记录后,服务将再次查看数据库并再次获取 10 条记录。
但我也在使用定时器,这样这个过程将在每 5 分钟后继续。现在,如果在某个时间,使用 WCF 上传的时间超过 5 分钟,我必须停止新的执行并等待它完成。
我该怎么表现。
每次计时器计时,将其禁用并在执行结束时再次启用它,以便在最后一次执行结束后 5 分钟再次计时。
这是锁定的理想方案。在下面的示例中,回调将每 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);
}
}
}
当你开始做你的事情时,为什么不设置一个布尔值(或者锁定更好)。
在循环中,检查您的布尔(或锁定)是否处于活动状态,然后跳过,这样您的下一批将在 5 分钟后运行。
使用 a Timer
to 计时五分钟,但告诉它不要重复:
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);
这将重新启动计时器。
只要方法调用在这段时间内完成,这种模式就可以让心跳每五分钟滴答一次,但如果方法调用仍在进行中,则不滴答。