Solved

Why does Response.End sometimes throw Thread was being aborted Exception?

Posted on 2011-02-27
7
2,043 Views
Last Modified: 2012-05-11
I have two different web pages that both create text files that are returned to the user via Response.WriteFile.

On the first page, in a button's click event, I have the following:
   SendFileResponse(Response, sFileName, "Data_" & sNow & ".csv")

Open in new window


In the other page, I instantiate a class and then, within a try - catch block, call a class method that makes the following calle:
   SendFileResponse(HttpContext.Current.Response, sServerFilename, "Extract_" & DateTime.Now.ToString("yyyyMMdd_HHmmss") & ".csv")

Open in new window


Both pages inherit from a base page which traps and logs any errors.

The code for SendFileResponse is as follows:
   Public Sub SendFileResponse( _
         ByRef oResponse As HttpResponse, _
         ByVal sServerFileName As String, _
         ByVal sUserFileName As String)

      Dim fiDownload As FileInfo = New FileInfo(sServerFileName)

      oResponse.Clear()
      oResponse.ClearHeaders()      ' Required to clear caching headers
      oResponse.AddHeader("Content-Disposition", "attachment; filename=" & sUserFileName)

      oResponse.AddHeader("Content-Length", fiDownload.Length.ToString())
      oResponse.ContentType = "application/octet-stream"
      oResponse.WriteFile(fiDownload.FullName)

      oResponse.End()
   End Sub

Open in new window


The first page works fine without throwing any errors. The second page often throws the following exception: System.Threading.ThreadAbortException: Thread was being aborted.

Can someone explain why one page throws the error and the other doesn't?
Thanks in advance.
0
Comment
Question by:ZekeLA
  • 3
  • 3
7 Comments
 
LVL 4

Accepted Solution

by:
Tuyau2poil earned 500 total points
ID: 34993838
in second page, you use try/catch but catch will nether be executed because response.end kill the current thread and nothing can be done after that. it seems that asp don't like to close himself it some code is still to be executed. In first page, reponse.end close thread at 'real' end of procedure.
anyway, Microsoft say that behavior is "by design" and can't be changed.
0
 
LVL 29

Expert Comment

by:Göran Andersson
ID: 34993860
The Response.End method always throws that exception, unless you use the overload that doesn't end the execution. It's the way that the framework uses to stop execution of the page and exit out to the code that finishes the response.

If you have a try-catch block that cathes any exception around the code where you use the Response.End, it will catch the exception. You should only catch the exceptions that you handle, not all kinds of exceptions.
0
 
LVL 1

Author Closing Comment

by:ZekeLA
ID: 34994202
Thanks Tuyau2poil, I understand why I was getting the error with the new code.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 29

Expert Comment

by:Göran Andersson
ID: 35000609
The accepted answer is not correct. It's just speculation, and has no basis in what's actually happens. The system has no sense of "code still to be executed".

The real reason is that you have a try-catch block in the second code, that catches the exception that the Response.End uses to exit out of the code. The Response.End method always throws that exception to exit out to the code that finishes the response, as I explained in my answer.
0
 
LVL 1

Author Comment

by:ZekeLA
ID: 35000710
That may be so GG but for now, the accepted answer matches the behavior better. Because of the base page Page_Error event, the error should always be caught. But it is only caught when called through the class object. I'll try looking into it further tonight. Perhaps the Page_Error event is ignoring certain errors.
0
 
LVL 1

Author Comment

by:ZekeLA
ID: 35004153
I've checked my code and I think I may have found part of the explanation but it still seems backwards to me. In my base page, I have the following code (stripped down):
        Private Sub Page_Error(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Error
            Call Me.PageError(Server, Page)
        End Sub

        Public Shared Sub PageError(ByVal oServer As System.Web.HttpServerUtility, ByVal oPage As Page) 'ByVal sender As Object, ByVal e As System.EventArgs)
            Dim ex As System.Exception = oServer.GetLastError
            Dim bEmailed As Boolean = SendErrorEmail(sErrorPageError & ex.Message, "", ex.ToString, oPage)

            oServer.ClearError()
        End Sub

Open in new window


Since Response.End is called from both pages, I would expect having a try catch block would trap and hide the error from being reported. And the other call should make its way to Page_Error normally. Even if Page_Error clears the error, it should still send me an email for the Abort error, but that doesn't happen from the first page. I only receive the notification from the second page.

For whatever reason, the abort exception gets swallowed up by the first page (no try catch) but not by the second page (has a try catch).
0
 
LVL 29

Expert Comment

by:Göran Andersson
ID: 35013275
The Error event is triggered when there is an unhandled exception in the page, but the exception that the Response.End method throws is handled before that. The system catches that exception and just continues to send the request.

If the exception used by Response.End wasn't handled by the system, it would always cause an Error event, and thus be pretty useless.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This video discusses moving either the default database or any database to a new volume.
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now