Comment bloquer une minuterie pendant le traitement de l'événement écoulé?
J'ai un timer qui ne doit pas traiter ses écoulé gestionnaire d'événements en même temps. Mais le traitement d'un événement Écoulé peut interférer avec les autres. J'ai mis en place ci-dessous la solution, mais quelque chose se sent mal; il semble que ce soit, je devrait être à l'aide de la minuterie de manière différente ou en utilisant un autre objet dans le filetage de l'espace. La minuterie semblait convenir le mieux, car j'ai besoin de vérifier périodiquement un état, mais parfois, la vérification de prendre plus de temps que mes intervalle. Est-ce la meilleure façon d'aborder cette question?
//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();
}
}
}
source d'informationauteur
Vous devez vous connecter pour publier un commentaire.
Vous pouvez définir AutoReset à false, alors explicitement remettre le chronomètre à zéro après que vous vous êtes fait manipuler. Bien sûr, la façon dont vous gérer cela dépend vraiment de la façon dont vous vous attendez à ce que la minuterie fonctionne. Cette façon de faire permettrait à votre minuterie à la dérive loin de l'intervalle spécifié (comme le ferait un arrêt et un redémarrage). Votre mécanisme permettrait à chaque intervalle d'incendie et d'être assuré, mais il peut entraîner un retard de non prise en charge des événements qui sont gérés maintenant, où près de l'expiration de la minuterie, ce qui cause le gestionnaire doit être invoquée.
J'ai l'habitude de l'arrêt de la minuterie pendant le traitement, entrez dans un try/finally bloc, et reprendre la minuterie lorsque vous avez terminé.
Si
LookForItWhichMightTakeALongTime()
va prendre du temps, je suggère de ne pas utiliser unSystem.Windows.Forms.Timer
parce que cela permettra de verrouiller votre thread de l'INTERFACE utilisateur et l'utilisateur peut tuer votre demande de penser qu'il a gelé.Ce que vous pouvez utiliser est un
BackgroundWorker
(avec unTimer
si cela est souhaité).Et vous pouvez appeler
RunWorkerAsync()
à partir de n'importe où vous voulez, même à partir d'unTimer
si vous le souhaitez. Et assurez-vous de vérifier si leBackgroundWorker
est en cours d'exécution déjà depuis l'appel deRunWorkerAsync()
quand il est en cours d'exécution se lever une exception.ou
et
ou
- Je utiliser le Système.Le filetage.Minuterie comme