[2.0][Threading] Arrêt et reprise de Thread
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.
Code:
1 2 3
|
private ReaderWrapper m_ReadWrapper;
private WriterWrapper m_WriteWrapper; |
La classe Agent est aussi composée de deux Threads : un "reader" et un "writer".
Code:
1 2 3
|
private Thread m_Reader;
private Thread m_Writer; |
Chaque Thread déclenche l'exécution d'une méthode Run() de son Wrapper respectif (Reader ou Writer).
Code:
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)); |
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:
1 2
|
while (!this.m_Agent.Stopped) this.m_Worker.Write(); |
Dans la classe Worker, les deux Threads sont synchronisés via un Monitor :
Code:
1 2 3 4 5 6 7
|
Lock (this)
{
Monitor.Wait(this);
TRAITEMENT ICI
Monitor.Pulse(this);
} |
Cette structure est commune à chacune des méthodes Read() et Write().
Problème
Quand je demande l'arrêt de l'Agent, cela fonctionne : les Theads sont suspendus :
Code:
1 2
|
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite); |
Quand je demande la reprise du travail de l'Agent une 1er fois, cela fonctionne :
Code:
1 2
|
if (this.m_Reader.ThreadState == ThreadState.WaitSleepJoin) this.m_Reader.Interrupt(); |
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:
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();
}
} |
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. :cry:
Je sais que c'est pas facile comme ça, mais si quelqu'u na déjà rencotnré ce cas, je suis preneur.