Я пытаюсь заменить старый код Threading.Timer на то, что может обрабатывать функцию async. Причина, по которой я делаю это, заключается в том, что вы не можете передавать Threading.Timer функцию async, не делая ее 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# так же хорошо, так как ответ будет в порядке.
EDIT1: Это должно быть потокобезопасным. Это является причиной моей озабоченности.
Должен ли он быть потокобезопасным? Потому что это не так, и если это не так, вам не нужно беспокоиться о гоночных условиях. – i3arnon
@ I3arnon Нужно ли быть потокобезопасным, к сожалению, возможно? Отредактировал вопрос, чтобы упомянуть об этом. – iguanaman
@ I3arnon Я понимаю, но он действительно должен быть потокобезопасным, поэтому я беспокоюсь об этом конкретно. – iguanaman