2012-05-15 5 views
6

Gli utenti della nostra applicazione scaricano un allegato almeno una volta in due secondi durante il giorno.Response.End() vs HttpContext.Current.ApplicationInstance.CompleteRequest()

scenario precedente:

Stavamo usando Response.End() per interrompere la connessione al client dopo l'utente scarica un allegato. Poiché abbiamo riscontrato problemi di prestazioni, abbiamo iniziato a registrare le eccezioni e una delle più ripetute era l'eccezione di interruzione del thread. Dal momento che stiamo ottenendo l'allegato da un servizio web, dobbiamo fare un po 'di pulizia e abbiamo ripulito il blocco try-catch-finally. Dopo alcune ricerche, ho capito che qualsiasi codice dopo Response.End() non verrà eseguito anche se è in un blocco finally. È giusto?

Scenario attuale:

ho letto il filo in overflow dello stack su Response.End() essendo dannosa e che deve essere utilizzato solo quando è realmente necessario, così ho deciso di utilizzare HttpContext ... .CompleteRequest() invece. Con questo codice, la pulizia è necessaria, ma l'HTML che viene reso viene aggiunto all'allegato scaricato. Ho provato a sovrascrivere il Render e RaisePostBackEvent suggerito nello stesso articolo ma il problema persiste ancora. Qualunque idea su come risolvere questo problema sarebbe utile.

Codice:

HttpContext.Current.Response.Clear(); 

Response.ClearContent(); 

Response.ClearHeaders(); 

Response.AddHeader("Content-Disposition", "attachment; filename=" + 
filename); 
Response.AddHeader("Content-Length", fileContent.Length.ToString()); 
Response.ContentType = "application/octet-stream"; 
Response.BinaryWrite(fileContent); 
Response.Flush(); 
+0

Si prega di non prefisso i titoli con "C#" e così via. Ecco a cosa servono i tag. –

+1

Sicuro. Mi dispiace per quello Ho appena iniziato a postare qui. Mi assicurerò di non ripeterlo. – user1396468

risposta

5

Response.End tiri internamente il ThreadAbortException di uccidere la richiesta - se avete bisogno di fare una sorta di pulizia, questo deve essere fatto prima di la chiamata a Response.End è fatta.

Response.Redirect e Response.End non interagiscono bene con i blocchi try/catch. Quindi, nella tua situazione, dovresti scrivere tutta la tua logica nel flusso di risposta nel tuo try/catch, quindi chiamare semplicemente Response.End dopo il blocco finale.

+0

Grazie per la risposta. Capisco che funzionerà, ma come posso sbarazzarmi di ThreadAbortException, il suo riempimento dei miei file di log e probabilmente anche di memoria sul server. C'è un modo per farlo senza la Response.End(). edit: Inoltre, se uso Response.End() dopo il mio blocco finally, sto eseguendo lo stesso problema di rendering dell'html che viene aggiunto al documento scaricato. Ad ogni modo posso risolvere il problema. Grazie per la risposta di nuovo. – user1396468

+0

Interrompe il wrapping di 'Response.End' nel tuo try/catch. 'Response.End' utilizza' ThreadAbortException' per terminare la risposta. È così che funziona. Stai praticamente recuperando l'eccezione del framework. – Tejs

+0

Ok. Non voglio avvolgere Response.End() in un try ... catch. Grazie per la segnalazione. puoi rispondere alla mia modifica, ho appena provato il codice che hai suggerito e ho di nuovo il problema html. Apprezzo molto le tue risposte. grazie. – user1396468

0

Vecchio Q, e non sono sicuro che sia d'aiuto, ma essenzialmente lo stesso del tuo esempio quando creo file PDF da consegnare al browser. Tuttavia, al termine dell'elaborazione, ho il seguente:

Response.OutputStream.Flush() 
    Response.OutputStream.Close() 
    Response.End() 

L'aggiunta di. Chiudi() in pratica. Sembra funzionare bene in produzione.

Ed: Appena trovato anche questo, menzionando Close(): Is Response.End() considered harmful?

Un altro approccio al problema è semplicemente prioritarie in Page_PreRender() e mettere il codice di distribuzione di contenuti in là (che tipo di senso funzionale). Quindi sicuramente non otterrai alcun codice HTML indesiderato e non dovrebbe esserci alcuna necessità di Response.End().

Problemi correlati