Bonjour à tous,
En m'essayant au multithreading, je suis tombé sur un comportement que je n'arrive pas bien à appréhender...
Bon voila le contexte :
Un appli désire envoyer des message sur vers une librairie multithreadée.
Lors de la réception de ce message, celui-ci est mis dans un objet de type queue. un autoresetevent est alors setté pour signaler le nouvel élément ajouter. Normalement cela voudrait dire que le thread sensé consommer les messages et qui attend les évenements à partir de la classe WaitHandle
while(WaitHandle.WaitAny(syncEvent.Events) == 0)
Le code sera plus parlant que mon discours...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
//Pour la classe recevant les messages
private static SyncEvent m_syncEvent = new SyncEvent();
private static Queue<string> m_queue = new Queue<string>();
private static MessageConsumer m_Consumer;
private static Thread m_ThreadConsumer;
//Pour démarrer le thread consommateur
public static void StartListening()
{
m_Consumer = new MessageConsumer(m_queue, m_syncEvent);
m_ThreadConsumer = new Thread(m_Consumer.ThreadRun);
m_ThreadConsumer.Name = "Thread Consommateur de Message";
m_ThreadConsumer.Start();
}
//Pour stopper le thread consommateur de message
public static void StopListening()
{
m_syncEvent.ExitThreadEvent.Set();
m_ThreadConsumer.Join();
}
public static void Add(string strMessage)
{
//while (!m_syncEvent.ExitThreadEvent.WaitOne(0, false))
lock (((ICollection)m_queue).SyncRoot)
{
//On ajoute le message à la queue commune au deux thread
m_queue.Enqueue(strMessage);
//On notifie le nouvel évement
m_syncEvent.NewItemEvent.Set();
}
}
//Du coté de la classe MessageConsumer
//Méthode du thread
internal void ThreadRun()
{
int count = 0;
//m_syncEvent est l'objet commun contenant Events
while (WaitHandle.WaitAny(m_syncEvent.Events) == 0)
{
//Traitement du message : Reflexion - plug in - DB??
//Traitement du message
lock (((ICollection)m_queue).SyncRoot)
{
while(m_queue.Count > 0)
{
string strMessage = m_queue.Dequeue();
//Traitement du message
}
}
//VAUT 1 après passage dans le while
count++;
}
} |
Dans la méthode main de mon appli je fais :
1 2 3 4 5 6 7 8
|
Messages.MessageLog.StartListening();
for (int i = 0; i < 200; i++)
{
Messages.MessageLog.Add("Count " + i);
}
Messages.MessageLog.StopListening(); |
Ce que je n'arrive pas à comprendre c est que count (dans threadRun()) vaut 1 après passage du while dans la méthode threadRun, alors que le Message peut etre notifié plusieurs fois.
Est ce que le fait de setter l'autoreset plusieurs fois de suite dans le meme thread (main ici) agit comme un autoreset et est ce que en général, il faut developper en pensant de cette manière ou alors y-a-til une pile d'appel à la méthode set qui permettrait de gérer signaler a WaitHandle.WaitAny le nombre exact de fois qu'a été setter l'autoressetEvent?
D'avance je vous remercie pour vos eclaircissement
Partager