Comment empêcher le Système.Les minuteries.La minuterie de la file d'attente pour l'exécution sur un pool de threads?
Il y a un problème avec le Système standard.Les minuteries.Minuteur de comportement. La minuterie élever Écoulé événement avec un certain intervalle de temps. Mais quand le temps d'exécution à l'intérieur Écoulé gestionnaire d'événement dépasser intervalle de minuterie alors pool de threads commencer les files d'attente de la gestion des événements. C'est un problème dans mon cas. C'est parce que avec mon Écoulé gestionnaire d'événement j'ai récupérer des données à partir de la base de données et de faire quelque chose avec elle et enfin d'enregistrer les résultats dans la base de données. Mais la manipulation des données doivent être fournies une seule fois. Donc, est-il un moyen pour éviter les files d'attente s'écouler des événements du Système.Les minuteries.Minuterie.
Comme illustration de ce problème, vous pouvez envisager prochain programme de test:
public class EntryPoint
{
private static void TimeProc(object state, ElapsedEventArgs e)
{
Console.WriteLine("Current time {0} on the thread {1}", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(20000);
}
static void Main(string[] args)
{
Console.WriteLine("Press <Enter> for finishing\n\n");
ThreadPool.SetMaxThreads(10, 10);
System.Timers.Timer MyTimer = new System.Timers.Timer(1000);
MyTimer.Elapsed += new ElapsedEventHandler(TimeProc);
MyTimer.Start();
Console.ReadLine();
MyTimer.Stop();
}
}
Et de sortie possibles seront comme ici:
Current time 03.02.2011 0:00:09 on the thread 4
Current time 03.02.2011 0:00:10 on the thread 5
Current time 03.02.2011 0:00:12 on the thread 6
Current time 03.02.2011 0:00:13 on the thread 7
Current time 03.02.2011 0:00:14 on the thread 8
Current time 03.02.2011 0:00:15 on the thread 9
Current time 03.02.2011 0:00:16 on the thread 10
Current time 03.02.2011 0:00:17 on the thread 11
Current time 03.02.2011 0:00:18 on the thread 12
Current time 03.02.2011 0:00:19 on the thread 13
Current time 03.02.2011 0:00:30 on the thread 4
Current time 03.02.2011 0:00:30 on the thread 5
Solutions possibles:
1) Il a été inspiré par:C# Minuterie vs Thread en Service
Et il y a un code comme ici concernant mentionné ci-dessus, exemple:
public class EntryPoint
{
private static System.Timers.Timer MyTimer;
private static void TimeProc(object state, ElapsedEventArgs e)
{
Console.WriteLine("Current time {0} on the thread {1}", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(20000);
MyTimer.Enabled = true;
}
static void Main(string[] args)
{
Console.WriteLine("Press <Enter> for finishing\n\n");
ThreadPool.SetMaxThreads(10, 10);
MyTimer = new System.Timers.Timer(1000);
MyTimer.AutoReset = false;
MyTimer.Elapsed += new ElapsedEventHandler(TimeProc);
MyTimer.Enabled = true;
Console.ReadLine();
}
}
2) la Deuxième façon est d'environ SynchronizingObject, mais c'est valable uniquement pour application Windows form ou supplémentaires nécessaires au développement de code pour la mise en œuvre de l'objet qui serait implémente ISynchronizeInvoke interface. Plus au sujet de cette façon, vous pouvez trouver ici
Donc, pour l'instant je préfère la première solution.
Si les données doivent être manipulés uniquement une fois alors pourquoi la répétition de minuterie ou voulez-vous dire au plus une fois tous les X temps?
Dans mon cas, une autre application de sauvegarder des données dans une base de données et mon application doit lire et le manipuler.
OriginalL'auteur apros | 2011-02-02
Vous devez vous connecter pour publier un commentaire.
Ce que j'ai l'habitude de faire dans ce cas c'est l'arrêt de la minuterie, au début de la
Elapsed
de gestionnaire et de commencer à nouveau à la fin. De cette façon, vous êtes seulement une tique à un moment.Mise à JOUR:
Par la MSDN lien, je pense que ce qu'ils veulent dire, c'est que vous pouvez définir votre propre drapeau (mais encore les tiques être), mais thread mesures de sécurité doivent être prises.
Le problème que vous rencontrez est par la conception. Si vous réglez une minuterie pour cocher toutes les trente secondes à une minute, vous vous en doutez deux tiques événements à feu, à droite? Si vous voulez qu'il se comporte différemment, c'est la façon de le faire.
MSDN demande ici: msdn.microsoft.com/en-us/library/... "Une façon de résoudre cette situation de concurrence est de définir un indicateur qui indique le gestionnaire d'événement pour l'événement Écoulé à ignorer les événements ultérieurs. ". Donc, je l'espère, il devrait y existe une autre façon de résoudre ce problème.
Si vous prenez cette approche, vous voulez redémarrer votre minuterie dans un bloc finally. Sinon, vous pouvez obtenir une exception lors du traitement et de la minuterie ne jamais redémarrer. Pour cela, et quelques autres raisons, je ne pense pas que c'est une bonne approche.
Cet extrait est très imparfaite, il n'est pas thread-safe. Interloqué est nécessaire. Examen MSDN exemple de code dans la Minuterie.Méthode Stop() docs.
OriginalL'auteur Mark Avenius
Je dirais tout simplement l'arrêter, puis le lancer après votre long de l'exécution de ce genre.
quels sont les avantages de cette action?
si vous parliez de thread aucun dans son cas, mais moi, pas longtemps, un aller, j'ai travaillé avec un client dans mon servie et j'ai dû être en mesure de capturer d'autres événements tout en laissant mon exécution de code à la fin. C'est pourquoi j'ai commencé à en parler.
si vous êtes conscient de ce que vous pouvez supprimer le gestionnaire de l'délégué avant l'arrêt de la minuterie, non ?
je sais.. mais jamais essayé.. semble être une bonne idée... je vais vérifier.. Merci
OriginalL'auteur Shekhar_Pro
Le comportement que vous voyez est par la conception. Soit définir une SynchronizingObject sur le timer, ou utiliser un autre timer (comme Système.Le filetage.Minuterie) qui n'a pas de tiques sur plusieurs threads.
en outre, la fixation d'un objet de synchronisation (si ma compréhension est correcte) n'empêchera pas de files d'attente, il suffit de le limiter à les traiter un à un de la file d'attente. voir msdn.microsoft.com/en-us/magazine/cc164015.aspx pour une comparaison des minuteries qui va dans le détail sur le comportement.
OriginalL'auteur Chris Shain
Je viens de créer un statique de la variable d'indicateur. De cette façon, mon minuterie continue à fonctionner, mais le code est simplement contournée si la méthode n'a pas terminé avant la prochaine minuterie de cycle.
Dans la méthode utilisée pour la minuterie, tester si un événement est en cours.
OriginalL'auteur Jose
Puisque aucune de ces réponses sont thread-safe, permettez-moi de proposer une qui est:
Comme vous pouvez le voir, la minuterie gestionnaire vérifie d'abord si elle n'est pas déjà en cours d'exécution, et ne procède à l'organisme si la valeur false est retourné. Si true est retourné, puis le gestionnaire renvoie rapidement et les tiques ne sont pas de file d'attente (à laquelle ils ont eu une simple instruction lock été utilisé). Voici les définitions de setTimerBodyRunning et setTimerBodyFinished:
Voici comment vous pouvez initialiser et lancer le chronomètre:
OriginalL'auteur public wireless