web-dev-qa-db-fra.com

Comment éviter Response.End () "Le fil était en cours d'abandon" Exception lors du téléchargement du fichier Excel

J'ai essayé de convertir mon ensemble de données en Excel et de télécharger ce fichier .J'ai obtenu le fichier Excel requis.Mais System.Threading.ThreadAbortException a été généré à chaque téléchargement Excel . Comment résoudre ce problème? .. Aidez-moi s'il vous plaît. ..

J'appelle cette méthode dans mon écran aspx. Il y a aussi la même exception qui a été levée par cette méthode.

J'appelle la fonction publique void ExportDataSet (DataSet ds) dans de nombreux écrans aspx et je gère également la méthode de consignation d'erreurs pour les exceptions qui sont déclenchées à l'exécution. Ces exceptions sont écrites dans un fichier .txt. Donc, cette même exception est enregistrée dans tous les fichiers txt de l'écran aspx.Je veux simplement éviter que cette exception jette du fichier de classe déclaré à l'aspx. Simplement je veux juste gérer cette exception dans mon fichier de classe de déclaration de méthode lui-même.

Appel de la méthode de fichier ASPX: Excel.ExportDataSet (dsExcel);

Définition de la méthode:

public void ExportDataSet(DataSet ds)
{

   try
   {
      string filename = "ExcelFile.xls";
      HttpResponse response = HttpContext.Current.Response;
      response.Clear();
      response.Charset = "";
      response.ContentType = "application/vnd.ms-Excel";
      response.AddHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
      using (StringWriter sw = new StringWriter())
      {
         using (HtmlTextWriter htw = new HtmlTextWriter(sw))
         {
             GridView dg = new GridView();
             dg.DataSource = ds.Tables[0];
             dg.DataBind();
             dg.RenderControl(htw);
             // response.Write(style);
             response.Write(sw.ToString());                                                
             response.End();                    // Exception was Raised at here
         }
      }
   }
   catch (Exception ex)
   {
      string Err = ex.Message.ToString();
      EsHelper.EsADLogger("HOQCMgmt.aspx ibtnExcelAll_Click()", ex.Message.ToString());
   }
   finally
   {                
   }
}
81
user3171957

J'ai recherché en ligne et ai vu que la Response.End() lève toujours une exception.

Remplacez ceci: HttpContext.Current.Response.End();

Avec ça:

HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
HttpContext.Current.Response.SuppressContent = true;  // Gets or sets a value indicating whether to send HTTP content to the client.
HttpContext.Current.ApplicationInstance.CompleteRequest(); // Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.
146
user3412640

Cela m'a aidé à gérer l'exception Thread was being aborted,

try
{
   //Write HTTP output
    HttpContext.Current.Response.Write(Data);
}  
catch (Exception exc) {}
finally {
   try 
    {
      //stop processing the script and return the current result
      HttpContext.Current.Response.End();
     } 
   catch (Exception ex) {} 
   finally {
        //Sends the response buffer
        HttpContext.Current.Response.Flush();
        // Prevents any other content from being sent to the browser
        HttpContext.Current.Response.SuppressContent = true;
        //Directs the thread to finish, bypassing additional processing
        HttpContext.Current.ApplicationInstance.CompleteRequest();
        //Suspends the current thread
        Thread.Sleep(1);
     }
   }

si vous utilisez le code suivant au lieu de HttpContext.Current.Response.End(), vous obtiendrez une exception Server cannot append header after HTTP headers have been sent.

            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.SuppressContent = True;
            HttpContext.Current.ApplicationInstance.CompleteRequest();

J'espère que ça aide

10
Binny

Semble être la même question que:

Quand un ASP.NET System.Web.HttpResponse.End () est appelé, le thread actuel est abandonné?

Donc, c'est par conception. Vous devez ajouter une capture pour cette exception et "l'ignorer" avec grâce.

4
robnick

Utilisez un bloc de capture spécial à l'exception de la méthode Response.End ()

{
    ...
    context.Response.End(); //always throws an exception

}
catch (ThreadAbortException e)
{
    //this is special for the Response.end exception
}
catch (Exception e)
{
     context.Response.ContentType = "text/plain";
     context.Response.Write(e.Message);
}

Ou supprimez simplement le Response.End () si vous construisez un gestionnaire de fichiers

3
SoliQuiD

Déplacez Response.End () en dehors des blocs Try/Catch et Using.

Il est supposé lancer une exception pour contourner le reste de la demande, vous n'étiez pas censé l'attraper.

bool endRequest = false;

try
{
    .. do stuff
    endRequest = true;
}
catch {}

if (endRequest)
    Resonse.End();
2
Steve

l'erreur pour Response.END (); c’est parce que vous utilisez un panneau de mise à jour asp ou tout contrôle utilisant javascript, essayez d’utiliser un contrôle natif depuis asp ou html sans JavaScript ni scriptmanager ou script et essayez à nouveau

1
Ivan Renteria Vidal

Pour moi ne fonctionne que 

HttpContext.Current.ApplicationInstance.CompleteRequest ().

https://stackoverflow.com/a/21043051/1828356

1
elgoya

Ce n’est pas un problème, mais c’est intentionnel. La cause première est décrite dans la page de support de Microsoft.

La méthode Response.End termine l'exécution de la page et décale l'exécution vers l'événement Application_EndRequest dans le pipeline d'événements de l'application. La ligne de code qui suit Response.End n'est pas exécutée.

La solution fournie est:

Pour Response.End, appelez la méthode HttpContext.Current.ApplicationInstance.CompleteRequest au lieu de Response.End pour ignorer l'exécution du code dans l'événement Application_EndRequest

Voici le lien: https://support.Microsoft.com/en-us/help/312629/prb-threadabortexception-occurs-if-you-use-response-end--response-redi

1
Anjani

Il suffit de mettre le

Response.End();

dans un bloc finally au lieu de dans le bloc try.

Cela a fonctionné pour moi !!!

J'ai eu la structure de code problématique suivante (avec l'exception)

...
Response.Clear();
...
...
try{
 if (something){
   Reponse.Write(...);
   Response.End();

   return;

 } 

 some_more_code...

 Reponse.Write(...);
 Response.End();

}
catch(Exception){
}
finally{}

et il jette l'exception. Je soupçonne que l'exception est levée lorsqu'il y a du code/travail à exécuter après response.End (); . Dans mon cas, le code supplémentaire était simplement le retour lui-même. 

Quand je viens de déplacer la réponse.End (); sur le bloc finally (et a laissé le retour à sa place - ce qui provoque le saut du reste du code dans le bloc try et le saut vers le bloc finally (pas simplement en quittant la fonction contenant)), l'exception a cessé de se produire. 

Les travaux suivants fonctionnent bien:

...
Response.Clear();
...
...
try{
 if (something){
   Reponse.Write(...);

   return;

 } 

 some_more_code...

 Reponse.Write(...);

}
catch(Exception){
}
finally{
    Response.End();
}
1
user2265251

J'ai supprimé le linkbutton de UpdatePanel et également commenté Response.End () Success !!!

1
nunopacheco

vider la réponse au client avant response.end ()

En savoir plus sur Response.Flush, méthode

Donc, utilisez le code mentionné ci-dessous avant response.End();

response.Flush();  
0
thejustv

J'ai utilisé tous les changements ci-dessus, mais je continuais à avoir le même problème sur mon application Web.

Ensuite, j'ai contacté mon fournisseur d'hébergement et leur ai demandé de vérifier si un logiciel ou un antivirus bloquant nos fichiers était transféré via HTTP. ou le FAI/réseau n'autorise pas le transfert de fichier.

Ils ont vérifié les paramètres du serveur et contourné le "pare-feu partagé du centre de données" pour mon serveur. Notre application peut maintenant télécharger le fichier.

J'espère que cette réponse aidera quelqu'un. C'est ce qui a fonctionné pour moi

0
J Sushil

J'ai trouvé la raison. Si vous supprimez les panneaux de mise à jour, cela fonctionne bien!

Je recommande cette solution: 

  1. N'utilisez pas response.End(); 

  2. Déclarez cette variable globale: bool isFileDownLoad;

  3. Juste après votre (response.Write(sw.ToString());) set ==> isFileDownLoad = true; 

  4. Remplacez votre rendu comme:

    /// AEG : Very important to handle the thread aborted exception
    
    override protected void Render(HtmlTextWriter w)
    {
         if (!isFileDownLoad) base.Render(w);
    } 
    
0
Abdelrahman ELGAMAL

J'ai trouvé que ce qui suit fonctionnait mieux ...

   private void EndResponse()
    {
        try
        {
            Context.Response.End();
        }
        catch (System.Threading.ThreadAbortException err)
        {
            System.Threading.Thread.ResetAbort();
        }
        catch (Exception err)
        {
        }
    }
0
that_roy