Unhandled Thread Exception

Résolu
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 - 20 janv. 2009 à 16:59
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 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.
    }
}

4 réponses

leprov Messages postés 1160 Date d'inscription vendredi 23 juillet 2004 Statut Membre Dernière intervention 21 octobre 2010 17
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 delegate void ThreadExceptionHandler(Exception ex);

private void ThreadExceptionMgr(Exception ex)
{
//blabla
}

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
}
}
3
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
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.
0
leprov Messages postés 1160 Date d'inscription vendredi 23 juillet 2004 Statut Membre Dernière intervention 21 octobre 2010 17
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
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
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.
0
Rejoignez-nous