Minuteurs

.NET propose trois minuteurs à utiliser dans un environnement multithread :

Notes

Certaines implémentations .NET peuvent inclure des minuteurs supplémentaires :

  • System.Windows.Forms.Timer : composant Windows Forms qui déclenche un événement à intervalles réguliers. Le composant ne possède pas d’interface utilisateur et est conçu pour une utilisation dans un environnement à thread unique.
  • System.Web.UI.Timer : composant ASP.NET qui effectue des publications (postback) de pages web asynchrones ou synchrones à intervalles réguliers.
  • System.Windows.Threading.DispatcherTimer : minuteur intégré à la file d’attente Dispatcher qui est traitée selon un intervalle de temps et une priorité spécifiés.

Classe System.Threading.Timer

La classe System.Threading.Timer vous permet d’appeler en permanence un délégué à des intervalles de temps spécifiés. Vous pouvez aussi utiliser cette classe pour planifier un appel unique à un délégué dans un intervalle de temps spécifié. Le délégué est exécuté sur un thread ThreadPool.

Quand vous créez un objet System.Threading.Timer, vous spécifiez un délégué TimerCallback qui définit la méthode de rappel, un objet d’état facultatif qui est passé au rappel, la durée d’attente avant la première invocation du rappel et l’intervalle de temps entre les invocations de rappel. Pour annuler un minuteur en attente, appelez la méthode Timer.Dispose.

L’exemple suivant crée un minuteur qui appelle le délégué fourni au bout d’une seconde (1000 millisecondes) la première fois et ensuite toutes les deux secondes. L’objet d’état de l’exemple sert à compter le nombre de fois que le délégué est appelé. Le minuteur s’arrête dès que le délégué a été appelé au moins 10 fois.

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

Pour plus d’informations et d’exemples, consultez System.Threading.Timer.

Classe System.Timers.Timer

L’autre minuteur qui peut être utilisé dans un environnement multithread est System.Timers.Timer qui, par défaut, déclenche un événement sur un thread ThreadPool.

Au moment de créer un objet System.Timers.Timer, vous pouvez spécifier l’intervalle de temps au cours duquel un événement Elapsed est déclenché. Utilisez la propriété Enabled pour indiquer si un minuteur doit déclencher un événement Elapsed. Si vous avez besoin qu’un événement Elapsed soit déclenché une seule fois à l’issue de l’intervalle spécifié, définissez le AutoReset sur false. La valeur par défaut de la propriété AutoReset est true, ce qui signifie qu’un événement Elapsed est déclenché régulièrement selon l’intervalle défini par la propriété Interval.

Pour plus d’informations et d’exemples, consultez System.Timers.Timer.

System.Threading.PeriodicTimer, classe

La classe System.Threading.PeriodicTimer vous permet d’attendre des cycles individuels d’un intervalle spécifié, le travail étant effectué après l’appel de PeriodicTimer.WaitForNextTickAsync.

Quand vous créez un objet System.Threading.PeriodicTimer, vous spécifiez un TimeSpan qui détermine la durée entre chaque cycle du minuteur. Au lieu de passer un rappel ou de définir un gestionnaire d’événements comme pour les classes de minuteur précédentes, vous effectuez le travail directement dans l’étendue, en attendant que WaitForNextTickAsync fasse avancer le minuteur de l’intervalle spécifié.

La méthode WaitForNextTickAsync retourne un ValueTask<bool> ; true en cas de déclenchement réussi du minuteur et false quand le minuteur a été annulé par l’appel de PeriodicTimer.Dispose. WaitForNextTickAsync peut éventuellement accepter un CancellationToken, qui aboutit à une TaskCanceledException quand une annulation a été demandée.

Pour plus d’informations, consultez System.Threading.PeriodicTimer.

Voir aussi