【问题标题】:Why Async Callback in System.Windows.Forms.Timer execute the await more times?为什么 System.Windows.Forms.Timer 中的 Async Callback 会执行多次等待?
【发布时间】:2022-11-19 01:08:56
【问题描述】:

我有一个带有等待数据库操作的异步回调的 Windows 窗体计时器,为什么在前一个回调尚未完成之前再次执行等待?我怎样才能解决这个问题? 许多人说 System.Windows.Forms.Timer 在执行新的回调操作之前等待前一个回调操作完成。

Private Async Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As  System.EventArgs) Handles Timer1.Tick 
  ' I have an array with 6 elements that i control 
  ' for executing database operation     
  For i=1 To 6
    If(some condition is true in array index)
      Await SaveAsync()
      'set to false the condition in array index after save
    End If
  Next       
End Sub

提前致谢。

【问题讨论】:

  • SaveAsync 是做什么的?如果太慢,计时器将在SaveAsync 有机会完成之前再次触发
  • @PanagiotisKanavos 最好不要在计时器中使用 async await 还是有另一种方法来纠正这个问题?
  • 没关系。定时器无论如何都会触发。 SaveAsync 是做什么的?定时器多久触发一次?
  • 每秒向数据库中插入数据。
  • @Craig 我读到 System.Windows.Forms.Timer 是唯一一个在开始新的之前完成前一个滴答声的计时器,我认为即使使用异步等待也能工作,但我错了,所以我创建了一个任务变量来保存任务等待并在下一行中我确实等待任务,并且我在每个计时器滴答中控制任务状态以验证他的状态直到完成。

标签: vb.net winforms async-await


【解决方案1】:

估计是因为异步调用的时间比你TimerInterval要长。这意味着 Tick 事件将在前一个事件处理程序完成执行之前再次引发。如果你想要的是上一个调用完成和下一个事件之间的特定时间间隔,那么你应该停止Timer,拨打电话,然后重新开始:

Private Async Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As  System.EventArgs) Handles Timer1.Tick 
    Timer1.Stop()
    Await SaveAsync()
    Timer1.Start()
End Sub

【讨论】:

    【解决方案2】:

    另一个答案告诉您如何解决问题,但没有说明问题出在哪里。

    a much older Stack Overflow question about the timer options,它对计时器滴答等待做出了可能具有误导性的陈述。讨论计时器滴答的潜在实现可能更有帮助:

    • 可以启动一个新线程来立即为报价提供服务
    • 可以发布稍后处理的通知

    System.Windows.Forms.Timer 做后者。特别是,它将通知作为 Windows 消息发布,当标准消息泵看到该消息时,它会引发 .NET,甚至在 UI 线程上进行处理。

    在大多数情况下,这意味着处理一次滴答将阻止下一次滴答发生任何事情,因为消息泵在事件处理程序执行时被阻塞。

    不过,这仅在消息泵被阻止时有效。有两种可能的方式可以使其畅通无阻:

    • 显式处理消息的代码,例如调用 Application.DoEvents 或直接针对调度程序编写的等效代码
    • Await 将隐式执行此操作,因为它将控制权返回给 UI,它将等待异步调用完成。这是设计使然,并且是 Await 的预期用例之一,以允许 UI 在执行异步调用时做出响应。

    与使用Await 的任何情况一样,您需要为重新进入做好准备并相应地设计您的代码。

    【讨论】:

      猜你喜欢
      • 2021-09-21
      • 1970-01-01
      • 2019-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多