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

Code : Sélectionner tout - Visualiser dans une fenêtre à part
while(WaitHandle.WaitAny(syncEvent.Events) == 0)
Le code sera plus parlant que mon discours...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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