关于.NET中数据库连接超时的管理

 

不知道大家在访问数据库,特别是远程数据库的时候有没有碰到这么一种情况。如果远程计算机没有打开,或者网络中断。这时不管你数据库连接设置的是多少秒,都会等待30-60秒左右的时间。这段时间其实是在等待不存在的主机的响应。

       C#中,其实我们完全可以控制这段时间,避免长时间的等待。因为这样对于一些系统,比如把数据库访问放在一个队列里面查询的系统来说,这样造成的时间浪费不可估计。因为正常情况下,打开数据库连接的时间很短。

       于是,我封装了一个类,通过多线程的方式,来控制这段时间。如果在指定时间,如5秒,没有连接上,则中断连接。并做出相应处理。这样,节约了很多的时间。

       在这里,我们首先简单介绍一下多线程。

       大家都知道,一个进程下面包含,多个线程。线程还分为主线程和后台线程。主线程中断后,后台线程会同时中断,反之,后台线程中断不会影响主线程。多线程编程中,如果没有把线程设置为后台线程,还不能用Abort()方法来中断线程。

       我封装了一个叫DbConnConsole的类。用来管理数据库连接超时,并支持多种数据库。

具体代码如下:


 

  1using System;
  2using System.Threading;
  3using System.Data;
  4using System.Data.SqlClient;
  5using Microsoft.Data.Odbc;
  6using System.Data.OleDb;
  7
  8
  9namespace DBConnConsole
 10{
 11
 12    /// <summary>
 13    /// 数据库类型
 14    /// </summary>

 15    public enum DatabaseType
 16    {
 17        SqlServer,           
 18        Odbc,
 19        Oracle,
 20        OleDB
 21    }

 22
 23
 24
 25
 26    /// <summary>
 27    /// 通过线程控制数据库连接时间管理
 28    /// </summary>

 29    public class DbConnConsole
 30    {
 31        private bool bIsConn = false;                    // 判断连接是否成功
 32        private Thread tdConn;                            // 连接数据库的线程
 33        private string strConn = null;                    // 连接字符串
 34        private int nTimeout = 0;                        // 超时时间
 35        private DatabaseType dbType;                    // 数据库类型
 36        private IDbConnection iConn = null;     // 数据库连接字符串对象接口 
 37        
 38
 39        /// <summary>
 40        /// 构造函数
 41        /// </summary>
 42        /// <param name="Conn">连接字符串</param>
 43        /// <param name="timeOut">超时时间(毫秒)</param>
 44        /// <param name="DBType">数据库类型</param>

 45        public DbConnConsole(string Conn, int timeOut, DatabaseType DBType)
 46        {
 47            strConn = Conn;
 48            nTimeout = timeOut;
 49            dbType = DBType;
 50        }

 51
 52
 53        /// <summary>
 54        /// 打开数据库
 55        /// </summary>
 56        /// <returns>连接对象接口</returns>

 57        public IDbConnection Open()
 58        {
 59            tdConn = new Thread(new ThreadStart(ConnDatabase));
 60            Thread tdTimeOut = new Thread(new ThreadStart(ConsoleTimeOut));
 61            tdConn.ApartmentState = ApartmentState.MTA;
 62            tdConn.IsBackground = true;
 63            tdTimeOut.Start();
 64            tdTimeOut.Priority = ThreadPriority.Highest;
 65            tdConn.Start();
 66            
 67            tdTimeOut.Join();             //连接超时控制线程,不然主线程会直接返回null.  !!!!
 68            return iConn;
 69        }

 70
 71
 72
 73        /// <summary>
 74        /// 超时控制
 75        /// </summary>

 76        private void ConsoleTimeOut()
 77        {
 78            Thread.Sleep(nTimeout);
 79            if (bIsConn == false)
 80            {
 81                tdConn.Abort();
 82                tdConn = null;
 83                iConn = null;
 84            }

 85        }

 86
 87
 88        /// <summary>
 89        /// 连接数据库
 90        /// </summary>

 91        private void ConnDatabase()
 92        {
 93            try
 94            {
 95            
 96                //根据数据连接类型创建数据访问类
 97                switch (dbType)
 98                {
 99                    case DatabaseType.SqlServer:
100                        iConn = new SqlConnection(strConn);
101                        iConn.Open();
102                        break;
103                    case DatabaseType.Odbc:
104                        iConn = new OdbcConnection(strConn);
105                        iConn.Open();
106                        break;
107                    case DatabaseType.OleDB:
108                        iConn = new OleDbConnection(strConn);
109                        iConn.Open();
110                        break;
111                }
            
112            
113                bIsConn = true;
114            }

115            catch (Exception exp)
116            {
117                System.Diagnostics.Debug.WriteLine(exp.ToString());
118            }

119            
120        }

121    }

122}

123
124       现在访问数据库则为:
125    string strConn = "data source=192.168.1.253;initial catalog=Northwind;"
126    + "user id=sa;pwd=098697;packet size=4096;Connect Timeout=10";
127
128     DbConnConsole dbConsole = new DbConnConsole(strConn, 3000, DatabaseType.SqlServer);
129     IDbConnection iConn = null;
130
131
132    iConn = dbConsole.Open();
133    
134    if (iConn != null)
135    {
136            
137        string strQuery = "select * from Employees";
138        SqlDataAdapter sqlDA = new SqlDataAdapter(strQuery, (SqlConnection)iConn);
139        DataSet ds = new DataSet();
140        sqlDA.Fill(ds);
141
142        dgTest.DataSource = ds.Tables[0].DefaultView;
143    }

144    else
145    {
146        MessageBox.Show("失败!");
147    }


 

最终,我们返回了一个数据库连接接口。

 

下面,我给出测试代码,以便测试程序正确性。


 

  string strConn = "data source=192.168.1.253;initial catalog=Northwind;"

    + "user id=sa;packet size=4096;Connect Timeout=10";

    

//其中的3000为控制的超时时间

     DbConnConsole dbConsole = new DbConnConsole(strConn, 3000, DatabaseType.SqlServer);

     IDbConnection iConn = null;

 

 

    iConn = dbConsole.Open();

   

    if (iConn != null)

    {

           

        string strQuery = "select * from Employees";

        SqlDataAdapter sqlDA = new SqlDataAdapter(strQuery, (SqlConnection)iConn);

        DataSet ds = new DataSet();

        sqlDA.Fill(ds);

 

        dgTest.DataSource = ds.Tables[0].DefaultView;

    }

    else

    {

        MessageBox.Show("失败!");

    }

  

 

这样,我们通过这个类,可以在任何数据库系统下面,实现连接超时管理,使系统功能更加的完善。

 

该代码在.net framework1.0 .net framework1.1下面均测试通过。

并在win2000,win2003,winxp下面均测试通过。

 

我的邮箱是 tony111082@hotmail.com

如果有什么问题,大家可以发邮件给我。

当然,也可以通过QQ17490957.

posted on 2005-11-13 12:15  刘寓  阅读(7464)  评论(1编辑  收藏  举报

导航