我有一個帶有等待資料庫操作的異步回呼的 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
提前致謝。
uj5u.com熱心網友回復:
這大概是因為異步呼叫花費的時間比Interval你的Timer. 這意味著該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
uj5u.com熱心網友回復:
另一個答案告訴您如何解決問題,但沒有說明問題出在哪里。
有一個關于計時器選項的 Stack Overflow 問題要早得多,它對計時器滴答等待做出了可能具有誤導性的陳述。討論計時器滴答的潛在實作可能更有幫助:
- 可以啟動一個新執行緒來立即為 tick 提供服務
- 可以發布稍后處理的通知
System.Windows.Forms.Timer做后者。特別是,它將通知作為 Windows 訊息發布,當標準訊息泵看到該訊息時,它會引發一個在 UI 執行緒上處理的 .NET 事件。
在大多數情況下,這意味著處理一次滴答將阻止下一次滴答發生任何事情,因為訊息泵在事件處理程式執行時被阻塞。
不過,這僅在訊息泵被阻止時有效。有兩種可能的方式可以使其暢通無阻:
- 顯式處理訊息的代碼,例如呼叫
Application.DoEvents或直接針對調度程式撰寫的等效代碼 Await將隱式執行此操作,因為它將控制權回傳給 UI,它將等待異步呼叫完成。這是設計使然,并且是 的預期用例之一Await,以允許 UI 在執行異步呼叫時做出回應。
在您使用 的任何情況下Await,您都需要為重新進入做好準備并相應地設計您的代碼。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/536757.html
標籤:网络窗体异步等待
上一篇:VMware安裝kali作業系統
