Question

J'ai une minuterie qui ne doit pas traiter en même temps le gestionnaire d'événements écoulé. Mais le traitement d’un événement Elapsed peut interférer avec d’autres. J'ai implémenté la solution ci-dessous, mais quelque chose ne va pas; il semble que je devrais soit utiliser le minuteur différemment, soit utiliser un autre objet dans l'espace de threading. La minuterie semblait mieux cadrer parce que je devais vérifier périodiquement son statut, mais la vérification prend parfois plus de temps que mon intervalle. Est-ce la meilleure façon d'aborder cela?

// member variable
private static readonly object timerLock = new object();
private bool found = false;


// elsewhere
timer.Interval = TimeSpan.FromSeconds(5).TotalMilliseconds;
timer.Elapsed = Timer_OnElapsed;
timer.Start();


public void Timer_OnElapsed(object sender, ElapsedEventArgs e)
{
  lock(timerLock)
  {
    if (!found)
    {
      found = LookForItWhichMightTakeALongTime();
    }
  }
}
Était-ce utile?

La solution

Vous pouvez définir la réinitialisation automatique sur false, puis réinitialiser explicitement le chronomètre une fois que vous avez fini de le gérer. Bien sûr, la façon dont vous gérez cela dépend vraiment de la manière dont vous attendez le fonctionnement de la minuterie. Le faire de cette façon permettrait à votre chronomètre de s'éloigner de l'intervalle spécifié (comme le ferait un arrêt et un redémarrage). Votre mécanisme permettrait à chaque intervalle de se déclencher et d’être traité, mais il pourrait en résulter un arriéré d’événements non gérés qui sont maintenant gérés et qui se rapproche de l’expiration du minuteur qui entraîne l’appel du gestionnaire.

timer.Interval = TimeSpan.FromSeconds(5).TotalMilliseconds;
timer.Elapsed += Timer_OnElapsed;
timer.AutoReset = false;
timer.Start();


public void Timer_OnElapsed(object sender, ElapsedEventArgs e)
{
    if (!found)
    {
      found = LookForItWhichMightTakeALongTime();
    }
    timer.Start();
}

Autres conseils

J'arrête généralement le chronomètre pendant son traitement, entre un bloc try / finally et relance le chronomètre une fois terminé.

Si LookForItWhichMightTakeALongTime () va durer longtemps, je suggérerais de ne pas utiliser de System.Windows.Forms.Timer car cela verrouillerait votre interface utilisateur. thread et l'utilisateur peut tuer votre application en pensant qu'elle est gelée.

Ce que vous pourriez utiliser est un BackgroundWorker (avec un Minuteur si vous le souhaitez).

public class MyForm : Form
{
  private BackgroundWorker backgroundWorker = new BackgroundWorker();

  public MyForm()
  {
    InitializeComponents();
    backgroundWorker.DoWork += backgroundWorker_DoWork;
    backgroundWorker.RunWorkerCompleted +=
                                backgroundWorker_RunWorkerCompleted;
    backgroundWorker.RunWorkerAsync();
  }

  private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
  {
    e.Result = LookForItWhichMightTakeALongTime();
  }

  private void backgroundWorker_RunWorkerCompleted(object sender,
                                             RunWorkerCompletedEventArgs e)
  {
    found = e.Result as MyClass;
  }
}

Et vous pouvez appeler RunWorkerAsync () à partir de n’importe où, et même à partir d’un minuteur si vous le souhaitez. Et assurez-vous simplement de vérifier si BackgroundWorker est déjà en cours d'exécution depuis l'appel de RunWorkerAsync () lors de son exécution générera une exception.

private void timer_Tick(object sender, EventArgs e)
{
  if (!backgroundWorker.IsBusy)
    backgroundWorker.RunWorkerAsync();
}
timer.enabled = false

ou

timer.stop();

et

timer.enabled = true

ou

timer.start();

J'utilise le System.Threading.Timer comme si

 class Class1
    {
        static Timer timer = new Timer(DoSomething,null,TimeSpan.FromMinutes(1),TimeSpan.FromMinutes(1));

        private static void DoSomething(object state)
        {
            timer = null; // stop timer

            // do some long stuff here

            timer = new Timer(DoSomething, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
        }



    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top