Finally körs verkligen ALLTID

Häromveckan gick vi igenom try/catch i skolan och det dök upp en del frågetecken kring vad finally-blocket ska vara till för. Skriver man kod efter try/catch-blocket så körs ju den. Men vad händer om man har kod i catch-blocket som till exempel skickar vidare användaren till en annan sida (Asp.NET-applikation)?

Jag bestämde mig för att testa detta. Först skapade jag en ny website-applikation och skrev in följande kod i Page_Load för startsidan Default.aspx;

Session["Message"] = "Everything is working";

try
{
    //trigga ett DivideByZeroException
    int divider = 0;
    int i = 3 / divider;
}
catch
{
    Response.Redirect("default2.aspx");
}
finally
{
    Session["Message"] = "Something went wrong";
}

Sedan la jag till en ny aspx, default2.aspx som helt enkelt skriver ut värdet på Session["Message"] till en label;

protected void Page_Load(object sender, EventArgs e)
{
    lblMessage.Text = Session["Message"].ToString();
}

Och resultatet är precis som min rubrik antyder, att finally-blocket körs innan Response.Redirect i catch-blocket skickar vidare till default2.aspx och resultatet blir att "Something went wrong" skrivs ut på sidan. Stegar man med debuggern körs dock faktiskt Response.Redirect-raden innan stegningen går vidare till finally, så det hela är minst sagt automagiskt... ;-)

Att fundera på

Session["Message"] = "BeforeTryCatch";

try
{
    Session["Message"] += " EnteringTry";
    //trigga ett DivideByZeroException
    int divider = 1;
    int i = 3 / divider;
    Session["Message"] += " LeavingTry";
}
catch
{
    Session["Message"] += " EnteringCatch";
    Response.Redirect("default2.aspx");
    Session["Message"] += " LeavingCatch";
}
finally
{
    Session["Message"] += " InFinally";
}

Session["Message"] += " AfterTryCatch";

Se koden ovan
1. Vad kommer Session["Message"] innehålla om något går fel i try-blocket?
2. Vad kommer Session["Message"] innehålla om inget går fel i try-blocket?

Markera här för rätt svar:
1. "BeforeTryCatch EnteringTry EnteringCatch InFinally". Alltså, raderna där "LeavingTry", "LeavingCatch" och "AfterTryCatch" står kommer aldrig att nås om något går fel i try-blocket eftersom Response.Redirect skickar vidare. Med finally-blocket får du en möjlighet att göra något innan användaren skickas vidare.
2. "BeforeTryCatch EnteringTry LeavingTry InFinally AfterTryCatch". Om inget går fel går allt utom catch-blocket igenom.
==================================================================================