Contexte
J'ai une application dont le but est de lire des données d'une base et de les écrire dans une autre.
Pour cela, j'ai une classe Agent composée d'un objet de la classe ReaderWrapper et un autre de la classe WriterWrapper.
La classe Agent est aussi composée de deux Threads : un "reader" et un "writer".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 private ReaderWrapper m_ReadWrapper; private WriterWrapper m_WriteWrapper;
Chaque Thread déclenche l'exécution d'une méthode Run() de son Wrapper respectif (Reader ou Writer).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 private Thread m_Reader; private Thread m_Writer;
La méthode Run() de chaque Wrapper appelle la méthode Read() ou Write() d'une classe Worker, tant que l'objet Agent n'a pas demandé l'arrêt :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 this.m_Reader = new Thread(new ThreadStart(this.m_ReadWrapper.Run)); this.m_Writer = new Thread(new ThreadStart(this.m_WriteWrapper.Run));
Dans la classe Worker, les deux Threads sont synchronisés via un Monitor :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 while (!this.m_Agent.Stopped) this.m_Worker.Write();
Cette structure est commune à chacune des méthodes Read() et Write().
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 Lock (this) { Monitor.Wait(this); TRAITEMENT ICI Monitor.Pulse(this); }
Problème
Quand je demande l'arrêt de l'Agent, cela fonctionne : les Theads sont suspendus :
Quand je demande la reprise du travail de l'Agent une 1er fois, cela fonctionne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
L'appel à la méthode Interrupt() lève une System.Threading.ThreadInterruptedException dans les classes ReaderWrapper et WriterWrapper. L'exception ets catchée puis un appel récursif reprend le travail :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 if (this.m_Reader.ThreadState == ThreadState.WaitSleepJoin) this.m_Reader.Interrupt();
Le problème, c'est que cela fonctionne la première fois seulement : seul 1 redémarage fonctionne. L'exception n'est pas levée la seconde fois et le travail ne repdrend pas.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 public void Run() { try { while (!this.m_Agent.Stopped) this.m_Worker.Write(); System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite); } catch(System.Threading.ThreadInterruptedException) { this.Run(); } }
Je sais que c'est pas facile comme ça, mais si quelqu'u na déjà rencotnré ce cas, je suis preneur.
Partager