Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 2012
-
20 janv. 2009 à 16:59
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 2012
-
22 janv. 2009 à 18:09
Salut..
protected override void OnClick( EventArgs e ) // Click sur une forme.
{
//base.OnClick( e );
try
{
Thread t = new Thread( new ThreadStart( DoSomething ) );
t.Start( );
t.Join( );
}
catch( Exception ex )
{
MessageBox.Show( ex.Message );
}
}
private void DoSomething( )
{
try
{
throw new ApplicationException( "Thread ex." );
}
catch
{
// Quel est le moyen le plus élégant de remonter l'exception
// dans le thread principal sans utiliser les évènements
// du genre ThreadException/UnhandledException. Merci
throw; // Exception non-gerée par le thread principal.
}
}
leprov
Messages postés1160Date d'inscriptionvendredi 23 juillet 2004StatutMembreDernière intervention21 octobre 201017 21 janv. 2009 à 12:35
vu que tu es dans un autre thread, tu vas pas pouvoir remonter dans le catch de ta méthode "OnClick", tu seras peut etre (surement) déjà sorti du bloc de code. Niveau archi cest pas faisable comme ca. Plusieurs solutions :
La première, pour moi la plus simple, cest d'utiliser un Invoke sur une méthode, pour faire un truc genre
private void DoSomething()
{
try
{
throw new ApplicationException("thread ex.");
}
catch (ThreadAbortException)
{
//ne pas empecher l'interrupt avec un catch vide
}
catch (Exception ex)
{
Invoke(new ThreadExceptionHandler(ThreadExceptionMgr), new object[]{ex});
}
}
enfin a la syntaxe pret quoi.
deuxieme solution a peu pret equivalente, mettre le DoSomething dans une backgroundWorker, et utiliser l'event de fin pour donner l'état du retour)
Troisieme solution, pour moi moins efficace mais qui pourrait être plus séquentiel dans ton code : une variable membre volatile qui serait l'exception, ainsi qu'un event system/join (le join semble plus judicieux). A ce moment tu check le resultat du DoSomething. L'inconvénient de cette solution est que ce n'est pas très élégant. L'avantage est que d'un point de vue "algo", ca correspond exactement a ce que tu cherche a faire. Pour économiser sur les variables membres et faire plus élégant, tu peux faire un peu conteneur (classe nested) dans ton form qui contiendrait la méthode DoSomething (et son lancement threadé), ainsi que l'exception de retour. ta méthode paint deviendrais qqch dans le genre :
private class C
{
private volatile Exception ret;
public void DoSomething()
{
privateDoSomething();
if (ret != null)
throw ret;
}
private void PrivateDoSomething()
{
try
{
Thread t = new Thread( new ThreadStart( DoSomething ) );
t.Start( );
t.Join( );
}
catch( Exception ex )
{
ret = ex;
}
}
}
protected override void OnClick( EventArgs e )
{
try
{
new C().DoSomething();
}
catch
{
//mbox
}
}
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 21 janv. 2009 à 17:19
Salut, merci pour ta réponse, moi aussi j'étais parti sur l'idée d'invoker un event à la fin du thread. la dernière solution est bonne à savoir mais elle me plait pas trop.
leprov
Messages postés1160Date d'inscriptionvendredi 23 juillet 2004StatutMembreDernière intervention21 octobre 201017 22 janv. 2009 à 09:22
L'idée de la derniere solution, cest surtout de masquer le coté un peu moyen dans un petit conteneur...il donne l'impression que cest sequentiel, il masque le thread, et il donne l'impression a la lecture que l'exception arrive directement...bref, cest surtout une feinte pour garder tout le code dans le "onclick" et voir le séquencement des traitements au premier coup d'oeil. apres, je suis quand meme (personnellement) plus fan du invoke
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 22 janv. 2009 à 18:09
Si ça interesse qlq'un plus tard..
Entre temps mon code à évolué et j'ai eu besoin de passer plusieurs paramètres au thread.. du coup je passe au délégué ParameterizedThreadStart une classe qui contient mes params + un param de type Exception qu je test à la fin du thread.