Unhandled Thread Exception

Résolu
Signaler
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
-
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
-
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

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