我想用一些可以處理異步函數的東西來替換舊的Threading.Timer代碼。我這樣做的原因是你不能將一個Threading.Timer傳遞給一個異步函數而不把它設置爲一個Async Sub,我不明白這是一個壞主意。用定製的異步定時器類替換Threading.Timer?
代碼我想替換;
Dim SaveTimer as New Threading.Timer(AddressOf SaveToFile, Nothing, 1000 * 60 * 5, 1000 * 60 * 5)
的SaveToFile是一個異步函數,所以我得到一個「的任務,從這個異步函數返回將被丟棄,並在它的任何異常忽略。考慮將其更改爲一個異步子所以它的異常傳播」的警示。
此計時器的目的是每隔5分鐘將它所在類的內容保存到文件中。但是,我也偶爾手動調用SaveToFile,如果我想要重置計時器。
隨着Threading.Timer我會這樣做;
Public Async Function ManuallySave As Tasks.Task
SaveTimer.Change(Timeout.Infinite, Timeout.Infinite)
Await SaveToFile
SaveTimer.Change(1000 * 60 * 5, 1000 * 60 * 5)
End Function
現在我知道如何安排任務使用Task.Delay完成,但我不知道如何停止它並重置。
這是我在異步計時器類的嘗試;
Public Class AsyncTimer
Private CancellationToken As New CancellationTokenSource
Private DelegateAction As Action(Of Tasks.Task) = Nothing
Public Sub New(DelegateAction As Action(Of Tasks.Task))
Me.DelegateAction = DelegateAction
End Sub
Public Async Function StartTimer(Interval As Integer, Optional Repeat As Boolean = False) As Tasks.Task
CancellationToken = New CancellationTokenSource
Do
Await Tasks.Task.Delay(Interval, CancellationToken.Token).ContinueWith(DelegateAction, CancellationToken.Token, TaskContinuationOptions.NotOnCanceled, TaskScheduler.Current)
Loop Until Not Repeat OrElse CancellationToken.IsCancellationRequested
End Function
Public Sub StopTimer()
CancellationToken.Cancel()
End Sub
End Class
我關心的是我打電話StopTimer,那麼不久之後startTimer所,其替換爲一個新的實例的CancellationToken。我擔心在取消令牌生效之前我會覆蓋它。
這是什麼解決方案?
我知道代碼是在VB中,但我也理解C#,所以無論是作爲答案都可以。
編輯1:這需要是線程安全的。這是我擔心的原因。
這應該是線程安全的嗎?因爲它不是,如果它不應該,你不需要擔心競爭條件。 – i3arnon 2014-09-13 13:35:26
@ I3arnon不幸的是,它確實需要線程安全,這可能嗎?編輯提出這個問題。 – iguanaman 2014-09-13 13:38:26
@ I3arnon我明白,但它確實需要是線程安全的,這就是爲什麼我特別關心這一點。 – iguanaman 2014-09-13 13:47:42