2009-06-18 8 views
18

Dans le code ci-dessous, parfois someFunctionCall() génère une exception "Thread was avorted". Comment se fait-il que le code dans le bloc de code B ne fonctionne jamais? Est-ce que ASP.NET démarre un nouveau thread pour chaque appel de méthode? J'ai été surpris de voir que lorsque cette exception se produit, le code du bloc b ne s'exécute jamais, la méthode retourne, et mon application continue à fonctionner. Quelqu'un peut-il expliquer cela?Exception ASP.NET "Le thread était en cours d'abandon" provoque la sortie de la méthode

Merci.

public void method() 
{ 
    // CODE BLOCK A 
    //... 


    try 
    { 
     someFunctionCall(); // this call is generating thread abort exception 
    } 
    catch(Exception ex) 
    { 
     // log exception message 
    } 

    // CODE BLOCK B 
    // ... 

} 

Répondre

29

Ceci est un ThreadAbortException; c'est une exception spéciale qui est automatiquement renvoyée à la fin de chaque bloc de saisie, sauf si vous appelez Thread.ResetAbort(). Les méthodes ASP .Net telles que Response.End ou Response.Redirect (sauf si vous transmettez false) lancent cette exception pour terminer le traitement de la page en cours; votre someFunctionCall() appelle probablement l'une de ces méthodes.

ASP .NET gère lui-même cette exception et appelle ResetAbort pour continuer le traitement.

+1

Alors, comment pourrais-je l'obtenir pour ignorer cette exception et continuer à exécuter le code dans le bloc B? –

+0

Êtes-vous sûr de vouloir? Si someFunctionCall réoriente ou la fin de la réponse, vous ne devriez probablement pas continuer – SLaks

+0

Qu'est-ce someFunctionCall faire? – SLaks

-2

Essayez de cette façon:

C'est ma méthode d'extension:

public static void WriteJSONObject(this HttpResponse response, object content) { 
      response.ContentType = "application/json"; 
      response.Write(new JavaScriptSerializer().Serialize(content)); 
      response.End(); 

} 

Et la logique:

public void RegisterUser() { 
    try { 
     Response.WriteJSONObject(new { Result = "See hello" }); 
    } 
    catch (Exception err) { 
     if (err.Message != "Thread was being aborted.") 
      Response.WriteJSONObject(new { Result = err.Message }); 
     else { 
      Response.End(); 
     } 
    } 
} 
+11

Ceci est faux. Vous ne devriez jamais comparer le message d'une exception à une chaîne codée en dur. Au lieu de cela, vous pouvez écrire 'catch (ThreadAbortException) {} catch (Exception ex) {...}'.De même, il est inutile d'appeler 'Response.End' s'il existe déjà une exception' ThreadAbortException'. – SLaks

+0

Cela fonctionne très bien même si ça a l'air faux. – Tarik

+0

P.s: Les solutions ci-dessus n'ont pas fonctionné pour moi comme la plupart des gens. Peu importe ce que j'ai fait n'a pas fonctionné, c'est la seule solution que j'ai trouvée et fonctionne très bien. – Tarik

1

Pour contourner ce problème, utilisez un des méthodes suivantes: Pour Response.End, appelez le HttpContext.Current.ApplicationInstance.CompleteRequest méthode au lieu de Response.End pour ignorer l'exécution de code à l'événement Application_EndRequest.

Pour Response.Redirect, utilisez une surcharge, qui passe Response.Redirect(String url, bool endResponse) false pour le paramètre endResponse pour supprimer l'appel interne à Response.End. Par exemple:

Response.Redirect ("nextpage.aspx", false); 

Si vous utilisez cette solution de contournement, le code qui suit Response.Redirect est exécuté. Pour Server.Transfer, utilisez plutôt la méthode Server.Execute.

Questions connexes