Magazine Internet

[Threading] Une alternative propre à Sleep()

Publié le 24 novembre 2009 par Jeremy.jeanson

Toute personne qui un jour s’est un peut intéressée à la qualité de son code est tombée sur des informations soulignant des soucis liés à la Méthode Sleep() de Thread… dire que ce n’est pas bon est une bonne chose!

Mais dire comment contourner le souci serrait peut être mieux ;)

Alors voici un peut exemple de ce qui peut être fait avec un Timer et un AutoResetEvent qui attend la fin d’une durée déterminée.

C#

/// <summary>
/// Attente
/// </summary> 
private static void Wait(Int32 tempoEnMillisecondes)
{
    // Création d'un handler d'attente
    System.Threading.AutoResetEvent e = new System.Threading.AutoResetEvent(false);

    // Tempo de 1 minute
    System.Threading.Timer timer = new System.Threading.Timer(
        delegate(Object state) {/*Mettre fin à l'attente de l'AutoResetEvent*/ e.Set(); },
        null,
        tempoEnMillisecondes,
        System.Threading.Timeout.Infinite);

    // Attente
    e.WaitOne();

    // Libération des ressources
    if (timer != null)
    {
        timer.Dispose();
        timer = null;
    }
    e = null;
}

Cet exemple étant loin d’être ce qu’il y a de plus propre (et ne pouvant pas être traduit en Vb), voici une approche plus classique :

Vb

Imports System.Threading

Public Class MonSleep

    Private m_AutoResetEvent As AutoResetEvent

    ''' <summary>
    ''' Attendre
    ''' </summary>
    ''' <param name="tempsEnMilliseconds"></param>
    ''' <remarks></remarks>
    Public Sub Sleep(ByVal tempsEnMilliseconds As Int32)
        Me.m_AutoResetEvent = New AutoResetEvent(False)

        Dim timer As New Timer( _
            AddressOf Me.CallBack, _
            Nothing, _
            tempsEnMilliseconds, _
            Timeout.Infinite)

        ' Attente
        Me.m_AutoResetEvent.WaitOne()

        ' Libération des ressources
        If (timer IsNot Nothing) Then
            timer.Dispose()
            timer = Nothing
        End If

        Me.m_AutoResetEvent = Nothing
    End Sub

    ''' <summary>
    ''' Callback du timer
    ''' </summary>
    ''' <param name="state"></param>
    ''' <remarks></remarks>
    Private Sub CallBack(ByVal state As Object)
        Me.m_AutoResetEvent.Set()
    End Sub

End Class
C#
using System.Threading;

public class MonSleep
{
    private AutoResetEvent m_AutoResetEvent;

    /// <summary>
    /// Attendre
    /// </summary>
    /// <param name="tempsEnMilliseconds"></param>
    /// <remarks></remarks>
    public void Sleep(Int32 tempsEnMilliseconds)
    {
        this.m_AutoResetEvent = new AutoResetEvent(false);

        Timer timer = new Timer(
            this.CallBack,
            null,
            tempsEnMilliseconds,
            Timeout.Infinite);

        // Attente
        this.m_AutoResetEvent.WaitOne();

        // Libération des ressources
        if (timer != null)
        {
            timer.Dispose();
            timer = null;
        }

        this.m_AutoResetEvent = null;
    }

    /// <summary>
    /// Callback du timer
    /// </summary>
    /// <param name="state"></param>
    /// <remarks></remarks>
    private void CallBack(Object state)
    {
        this.m_AutoResetEvent.Set();
    }
}

Bien entendu il faut instancier un objet MonSleep pour déclencher le Sleep.


Retour à La Une de Logo Paperblog

A propos de l’auteur


Jeremy.jeanson 1573 partages Voir son profil
Voir son blog

l'auteur n'a pas encore renseigné son compte l'auteur n'a pas encore renseigné son compte

Dossiers Paperblog