Closing a conneciton in the “unload” method

◇◆丶佛笑我妖孽 提交于 2019-12-01 17:45:18

I have no definitive knowledge about if this is safe, but I poked through the Source code for the System.Web.UI.Page class and the unload event is triggered by the private ProcessRequestCleanup() unless the request is asyncronous or a cross page request. The call to the clean up method is inside a finally block coupled to a try block that's surrounding the ProcessRequest. Process request is triggering all the page life cycle events from PreInit to Render. That would mean that Unload will always be triggered (except for in the async and cross page cases), even if an exception occur.

However I would feel very uneasy having this code in my pages since the behaviour of unload isn't exactly documented.

Pranay Rana

I always make use of using block soemthing as below

using( SqlConnection)
{

}

so that it never cause any problem

if you dont want to write code for opening connection again and again create one class

public class SqlConnectionManager
{
    public SqlConnection GetSqlConnectionManager()
    {
       //create and return connection
       //SqlConnection con = new SqlConnection();
       //return con;
     }

}

In You class files

SqlConnection conn = null;
using (conn = (new SqlConnectionManager()).GetSqlConnectionManager())
{
     //do work with connection
}

So by the above way you do not need to write code again and again and there is also no need to write code to close connection because its automatically get dispose by using block.

A (very) quick test (VS2010 web server, .net v4) has shown me that the Unload event is called when an unhandled exception is raised (at least if raised in Page_Load), so the principle looks like it should work.

The pattern as listed in the example is only dispose'ing the connection if the connection was open.

As _conn is protected, pages descended from BasePage can interact with _conn and modify its value. There are two ways for descendant classes to break the pattern:

  1. Call _conn.Close() directly. If the connection is not open, it is not disposed in EndConnection.

  2. Modify the value of _conn by either setting it to null or assigning a new instance of DBConnection to it.

Consider changing your EndConnection method, so that _conn is always disposed.

private void EndConnection(object sender, EventArgs e)
{
    if (_conn == null)
    {
       return;
    }
    if (_conn.Connection.State == ConnectionState.Open)
    {
         _conn.Close();
    }
    _conn.Dispose(); // always dispose even if not actually open. It may have been closed explicitly elsewhere.
}

Case 2 can't be caught by EndConnection. Consider making _conn private and providing a getter property:

private DBConnection _conn;

protected DBConnection Connection {
     get 
     {
         return _conn;
     }
}

which prevents descendant classes from changing the value of _conn.

Lastly, is DBConnection a class of your own? I only ask as you quote "_conn.Connection.State" rather than just _conn.State. If so, just double check that the Dispose method of DBConnection disposes its Connection instance correctly.

EDIT: As per PHeiberg's answer this is definitely possible in .net 4 and one can assume unload will always be called.

I checked the .net 2.0 code as well and the same is also true there.

Jethro

No. Take the following example.

What happens if the user closes the browser? The Unload function will then not be called and you will have an open connection to the database.

This Unload question on StackOverflow has a similar problem that you are having.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!