Timers
.NET tillhandahåller tre timers som ska användas i en flertrådad miljö:
- System.Threading.Timer, som kör en enda motringningsmetod i en ThreadPool tråd med jämna mellanrum.
- System.Timers.Timer, som som standard genererar en händelse i en ThreadPool tråd med jämna mellanrum.
- System.Threading.PeriodicTimer, vilket gör att anroparen kan utföra arbete efter att ha väntat på enskilda tick i timern.
Kommentar
Vissa .NET-implementeringar kan innehålla ytterligare timers:
- System.Windows.Forms.Timer: en Windows Forms-komponent som utlöser en händelse med jämna mellanrum. Komponenten har inget användargränssnitt och är utformad för användning i en entrådad miljö.
- System.Web.UI.Timer: en ASP.NET komponent som utför asynkrona eller synkrona sidinlägg med jämna mellanrum.
- System.Windows.Threading.DispatcherTimer: en timer som är integrerad i Dispatcher kön som bearbetas med ett angivet tidsintervall och med en angiven prioritet.
Klassen System.Threading.Timer
Med System.Threading.Timer klassen kan du kontinuerligt anropa ett ombud vid angivna tidsintervall. Du kan också använda den här klassen för att schemalägga ett enskilt anrop till ett ombud inom ett angivet tidsintervall. Ombudet körs i en ThreadPool tråd.
När du skapar ett System.Threading.Timer objekt anger du ett TimerCallback ombud som definierar motringningsmetoden, ett valfritt tillståndsobjekt som skickas till motringningen, hur lång tid det tar innan återanropet första gången och tidsintervallet mellan återanrop. Om du vill avbryta en väntande timer anropar du Timer.Dispose metoden.
I följande exempel skapas en timer som anropar det angivna ombudet för första gången efter en sekund (1 000 millisekunder) och sedan anropar den varannan sekund. Tillståndsobjektet i exemplet används för att räkna hur många gånger ombudet anropas. Timern stoppas när ombudet har anropats minst 10 gånger.
using namespace System;
using namespace System::Threading;
ref class TimerState
{
public:
int counter;
};
ref class Example
{
private:
static Timer^ timer;
public:
static void TimerTask(Object^ state)
{
Console::WriteLine("{0:HH:mm:ss.fff}: starting a new callback.", DateTime::Now);
TimerState^ timerState = dynamic_cast<TimerState^>(state);
Interlocked::Increment(timerState->counter);
}
static void Main()
{
TimerCallback^ tcb = gcnew TimerCallback(&TimerTask);
TimerState^ state = gcnew TimerState();
state->counter = 0;
timer = gcnew Timer(tcb, state, 1000, 2000);
while (state->counter <= 10)
{
Thread::Sleep(1000);
}
timer->~Timer();
Console::WriteLine("{0:HH:mm:ss.fff}: done.", DateTime::Now);
}
};
int main()
{
Example::Main();
}
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
private static Timer timer;
static void Main(string[] args)
{
var timerState = new TimerState { Counter = 0 };
timer = new Timer(
callback: new TimerCallback(TimerTask),
state: timerState,
dueTime: 1000,
period: 2000);
while (timerState.Counter <= 10)
{
Task.Delay(1000).Wait();
}
timer.Dispose();
Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: done.");
}
private static void TimerTask(object timerState)
{
Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: starting a new callback.");
var state = timerState as TimerState;
Interlocked.Increment(ref state.Counter);
}
class TimerState
{
public int Counter;
}
}
Imports System.Threading
Module Program
Private Timer As Timer
Sub Main(args As String())
Dim StateObj As New TimerState
StateObj.Counter = 0
Timer = New Timer(New TimerCallback(AddressOf TimerTask), StateObj, 1000, 2000)
While StateObj.Counter <= 10
Task.Delay(1000).Wait()
End While
Timer.Dispose()
Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: done.")
End Sub
Private Sub TimerTask(ByVal StateObj As Object)
Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: starting a new callback.")
Dim State As TimerState = CType(StateObj, TimerState)
Interlocked.Increment(State.Counter)
End Sub
Private Class TimerState
Public Counter As Integer
End Class
End Module
Mer information och exempel finns i System.Threading.Timer.
Klassen System.Timers.Timer
En annan timer som kan användas i en miljö med flera flöden är System.Timers.Timer att som standard genererar en händelse i en ThreadPool tråd.
När du skapar ett System.Timers.Timer objekt kan du ange tidsintervallet för att skapa en Elapsed händelse. Använd egenskapen Enabled för att ange om en timer ska generera en Elapsed händelse. Om du bara vill att en Elapsed händelse ska aktiveras en gång efter att det angivna intervallet har förflutit anger du AutoReset till false
. Standardvärdet för AutoReset egenskapen är true
, vilket innebär att en Elapsed händelse utlöses regelbundet med det intervall som definieras av Interval egenskapen.
Mer information och exempel finns i System.Timers.Timer.
Klassen System.Threading.PeriodicTimer
Med System.Threading.PeriodicTimer klassen kan du invänta enskilda tick i ett angivet intervall och utföra arbete efter att ha anropat PeriodicTimer.WaitForNextTickAsync.
När du skapar ett System.Threading.PeriodicTimer objekt anger du en TimeSpan som avgör hur lång tid det tar mellan varje tick i timern. I stället för att skicka ett återanrop eller ställa in en händelsehanterare som i föregående timerklasser utför du arbete direkt i omfånget i väntan på WaitForNextTickAsync att föra timern framåt med det angivna intervallet.
Metoden WaitForNextTickAsync returnerar en ValueTask<bool>
; true
vid lyckad utskjutning av timern och false
när timern har avbrutits genom att anropa PeriodicTimer.Dispose. WaitForNextTickAsync om du vill kan du acceptera en CancellationToken, vilket resulterar i en TaskCanceledException när en annullering har begärts.
Mer information finns i System.Threading.PeriodicTimer.