quarta-feira, 17 de agosto de 2011

Thread was being aborted e HttpWebResponse.Redirect

Olá, gostaria de retomar as postagens neste blog com um tema simples, mas que pode ser muito útil.


O problema:


Recentemente um colega expos um problema comum ao utilizar o Responde.Redirect(url) no ASP.NET. O cenário era o seguinte: ele possuía um trecho de código com try...catch...finally, e dentro dele havia um Response.Redirect(url). Ele notou que a página sempre dava erro. Eis um exemplo que ilustra o cenário:




Protected Sub btnGo_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGo.Click
Dim _Connection As SqlConnection = Nothing
Try
_Connection = New SqlConnection("Data Source=.;Initial Catalog=master;Integrated Security=SSPI;")
Dim _Command As New SqlCommand("Select Count(*) From Sys.Objects Where Type = 'U'", _Connection)
Dim _Result As Int32

_Connection.Open()
_Result = Convert.ToInt32(_Command.ExecuteScalar())

Response.Redirect("Result.aspx?r=" & _Result.ToString())
Catch ex As Exception
Response.Redirect("Result.aspx?r=" & Server.UrlEncode("Erro ao buscar os dados. " & ex.Message))
Finally
If _Connection IsNot Nothing Then
_Connection.Close()
End If
End Try
End Sub

O erro gerado pela página era sempre o mesmo: Thread was being aborted.


Solução:


A solução é substituir os dois Response.Redirect(url) do código por Response.Redirect(url, False). Desta forma, por exemplo:




Response.Redirect("Result.aspx?r=" & _Result.ToString(), False)

Explicação:


O Response.Redirect(url) apenas chama o método Response.Redirect(url, True). Este segundo parâmetro do tipo Boolean indica se, antes de enviar o HTTP Redirect para o Browser do cliente, a execução da página deve ser interrompida ou não.


Caso passemos True, o método Redirect tentará interromper a execução, porém, devido ao bloco Try...Catch...Finally, ele obterá um erro: pois a thread na qual a página está sendo executada só poderá ser interrompida após o Finally ser executado.


Passando False no segundo parâmetro, o método aguardará o ciclo de vida da página ser executado por completo antes de enviar o HTTP Redirect ao browser.


Atenção: Em muitos casos é interessante interromper o processamento da página no Redirect, principalmente quando há algum processamento pesado que não precise ser executado caso haja o Redirect. Não é à toa que o comportamento padrão (quando não passamos o parâmetro) é o de interromper o processamento.

Nenhum comentário: