Loupe

Un helper pour différer l’exécution d’une action

Pour rendre nos applications fluides et réactives il faut contrôler le nombre d’accès aux opérations coûteuses en temps (appel à la base de donnée, sur le système de fichier, …), pour les effectuer le moins de fois possible.

Or dans certains cas on ne peut pas prédire à l'avance si une méthode va être appelée une fois ou plusieurs fois dans un court laps de temps.

Par exemple lorsque l'on s'abonne à l'évènement CollectionChanged d'une ObservableCollection, ou lorsque l’on veut déclencher une action lors d’un changement de texte.

Une solution possible

Une des stratégies pour résoudre ce problème est de contrôler ces accès coûteux et les effectuer les moins de fois possible.

Dans cette optique j’ai développé un petit helper, qui retarde l’exécution d’une action, si entre ce délai une action est lancée la précédente ne sera jamais exécuté.

L’utilisation est très simple :

_delayActionHelper.ExecuteActionAfterDelay(async () =>
{
    AMethodExecuteOnlyOneTime();
});


DelayHelper

L’implémentation :

/// <summary>
/// Helper which delay an action. 
/// If the same action is trigger wait to run it
/// </summary>
public class DelayActionHelper
{
    #region Fields
    DispatcherTimer _timer;
    Action _action;
    DateTime _dateToExecute;
    readonly int _delaySeconds;
    #endregion

    public DelayActionHelper(int delaySeconds = 3)
    {
        _delaySeconds = delaySeconds;
    }
    /// <summary>
    /// Enables the timer.
    /// </summary>
    void EnableTimer()
    {
        if (_timer == null)
        {
            _timer = new DispatcherTimer();
            _timer.Interval = TimeSpan.FromSeconds(_delaySeconds);
            _timer.Tick += _timer_Tick;
        }
        if (!_timer.IsEnabled)
            _timer.Start();
    }

    private void _timer_Tick(object sender, object e)
    {
        //Si on peut exécuté l’action alors on l’exécute…
        if (DateTime.Now > _dateToExecute)
        {
            var action = _action;
            //On a exécuté l’action on peut arrêter le timer
            _timer.Stop();
            if (action != null)
            {
                action();
                _action = null;
            }
        }
    }
    /// <summary>
    /// Execute action after a delay
    /// </summary>
    /// <param name="action">The action to execute.</param>
    public void ExecuteActionAfterDelay(Action action)
    {
        _action = action;
        _dateToExecute = DateTime.Now.AddSeconds(_delaySeconds);
        EnableTimer();
    }
}


Happy Coding Rire
Photo de profil

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus