C# Windows服务有时会多次命中API

C# Windows服务有时会多次命中API,c#,.net,windows-services,C#,.net,Windows Services,我正在使用一个windows服务来调用API,在Sql表中获取响应和更新。它工作正常,但有时它会两次命中API。我找不到背后的理由。这是我的密码 protected override void OnStart(string[] args) { this.timer = new System.Timers.Timer(15000D); this.timer.AutoReset = true; this.timer.Elapsed += new System.Timers.Elapsed

我正在使用一个windows服务来调用API,在Sql表中获取响应和更新。它工作正常,但有时它会两次命中API。我找不到背后的理由。这是我的密码

protected override void OnStart(string[] args)
{
  this.timer = new System.Timers.Timer(15000D);
  this.timer.AutoReset = true;
  this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
  this.timer.Start();
}
protected override void OnStop()
  {
     this.timer.Stop();
     this.timer = null;
 }
protected void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
  this.proccessQue();
}
这里是proccessQue()方法

//选择记录表单表
SqlDataAdapter adap=newsqldataadapter(“从表名中选择*,表名为0,日期>日期添加(分钟,-5,GETDATE())”,conn);
DataTable dt=新的DataTable();
adap.Fill(dt);
对于(int i=0;i

请帮帮我,我哪里做错了。

根据我对原始问题的评论,有几件事要看

  • 根据查询结果,API将被命中0-n次。现在,计时器将在每个间隔异步执行
    timer\u appeased()
    方法。因此,如果
    processQue()
    方法花费的时间超过15秒,则可能会对每个项多次调用API
  • 因此,一个选项是在
    processQue()
    方法完成时,停止计时器执行进程逻辑和
    Start()
    计时器。例如:

    protected void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
      this.timer.Stop(); //stop the timer 
      this.proccessQue(); //process the queue
      this.timer.Start(); //restart the timer
    }
    
    因此,这确保了
    processQue()在再次调用
    timer\u appeased()
    事件之前完成

    现在,如果
    processQue()
    方法中出现异常,执行将不会继续。这取决于您如何处理,但只需简单的
    尝试。。catch
    将处理异常(不正确,但会)

    现在,我对代码的第二个关注点是类的使用,而不是正确地处理事物,这与执行多次的原因无关

    首先。。这是基于意见的,但是不需要数据表,而是将整个结果读入内存。看起来您只使用了Sql查询的两列(不确定
    rId
    来自何处),因此不要使用
    *
    ,而是定义实际需要的列名。这将减少Sql查询中查询和传输的数据量。在小查询中可能看起来微不足道,但在大查询和大数据集中可能会产生很大的差异

    我看到的下一个问题是在不处理它们的情况下使用IDisposable

  • SqlDataAdapter
  • StreamReader
  • SqlCommand

  • 这些都是从so继承的类,应该封装在一个语句中,或者手动调用该方法。

    Multiple things 1。您的API调用位于记录循环中。因此,将根据循环的结果命中0-n次。您的查询可能返回多个方法。2.您的processQueue方法是否可能比计时器的每个已用事件花费更长的时间?我的建议是1。检查查询结果,因为它可能返回多条记录2。在已用事件进程中停止计时器,然后重新启动队列。最后,考虑到这一点,您最好使用异步/等待模式,并为web请求使用更健壮的HttpClient类。哦,最后,您有相当多的IDisposable未被处理是的,查询可能返回超过1行。如何在经过的事件中停止计时器处理队列,然后重新启动它?请帮帮我。我将此服务用于充值网站,因此无法因充值时间而增加计时器已用时间。在计时器已用事件中,调用timer.Stop()。然后调用processQueue方法,然后调用timer.Start()。这将确保进程队列完成时计时器仅等待15秒。您是指受保护的无效计时器(对象发送方,System.Timers.ElapseDevenTargets e){This.timer.Stop();This.proccessQue();}像这样吗?
    protected void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
      this.timer.Stop(); //stop the timer 
      this.proccessQue(); //process the queue
      this.timer.Start(); //restart the timer
    }