c# 连接池的设置与使用

原由:许多用户可能在查询相同的数据库以获取相同的数据。在这些情况下,可以通过使应用程序共享到数据源的连接来提高应用程序的性能。否则,让每个用户打开和关闭单独的连接的开销会对应用程序性能产生不利影响。这样就有了连接池。

实现:

C#在连接字符串中设置连接池

如果使用的是 OleDbConnection、OdbcConnection 或 OracleConnection 类,则连接池将由提供程序自动处理,所以您不必自己进行管理。

如果使用的是 SqlConnection 类,则连接池被隐式管理,但也提供选项允许您自己管理池。

连接使用Open()方法打开连接,这时候连接池就会初始化并建立设定的最小连接数。在使用完连接时一定要关闭连接,以便连接可以返回池。要关闭连接使用Close()

当连接数满了并且申请连接的时间超过设置连接等待的时间时,使用“异步进程”,对数据库进行异步操作,确保连接能够及时调用Close方法关闭连接,这样能大大减少正在使用的连接数。

当数据库操作和访问频繁的时候,减少创建连接和打开连接所耗的时间,提升数据库服务器的性能。 这里将详细分析C#数据库连接池。

使用C#数据库连接池

连接到数据库服务器通常由几个需要软长时间的步骤组成。必须建立物理通道(例如套接字或命名管道),必须与服务器进行初次连接,必须分析连接字符串信息,必须由服务器对连接进行身份验证,等等。

实际上,大部份的应用程序都是使用一个或几个不同的连接配置。当应用程序的数据量和访问量大的时候,这意味着在运行应用程序的过程中,许多相同的连接将反 复地被打开和关闭,从而会引起数据库服务器效率低下甚至引发程序崩溃。为了确保应用程序的稳定和降低性能成本,我们可以在ADO.NET中使用称为连接池的优化方法来管理维护连接。

C#数据库连接池可以减少创建连接的次数。定义最小连接数(固定连接数),当用户在连接上调用Open,连接池就会检查池中是否有可用的连接。如果发现有连接可用,会将该连接返回给调用者,而不是创建新连接。应用程序在该连接上调用Close时,连接池会判断该连接是否在最小连接数之内,如果“是”会将连接回收到活动连接池中而不是真正关闭连接,否则将烧毁连接。连接返回到池中之后,即可在下一个Open调用中重复使用。

创建C#数据库连接池

以下示例使用C#连接SQL数据库:

 class DbConn
    {
        //using System.Data;
        //using System.Data.SqlClient;
        private const int MaxPool = 10;         //最大连接数
        private const int MinPool = 5;          //最小连接数
        private const bool Asyn_Process = true; //设置异步访问数据库
        private const bool Mars = true;         //在单个连接上得到和管理多个、仅向前引用和只读的结果集(ADO.NET2.0) 
        private const int Conn_Timeout = 15;    //设置连接等待时间
        private const int Conn_Lifetime = 15;   //设置连接的生命周期
        private string ConnString = "";         //连接字符串      
        private SqlConnection SqlDrConn = null;  //连接对象

        public DbConn()//构造函数
        {
            ConnString = GetConnString();
            SqlDrConn = new SqlConnection(ConnString);
        }

        private string GetConnString()
        {
            return "server=localhost;"
                + "integrated security=sspi;"
                + "database=pubs;"
                + "Max Pool Size=" + MaxPool + ";"
                + "Min Pool Size=" + MinPool + ";"
                + "Connect Timeout=" + Conn_Timeout + ";"
                + "Connection Lifetime=" + Conn_Lifetime + ";"
                +"Asynchronous Processing=" + Asyn_Process + ";";
                //+ "MultipleActiveResultSets=" + Mars + ";";
        }
       
        public DataTable GetDataReader(string StrSql)//数据查询
        {                    
            //当连接处于打开状态时关闭,然后再打开,避免有时候数据不能及时更新
            if (SqlDrConn.State == ConnectionState.Open)
            {
                SqlDrConn.Close();                
            }
            try
            {
                SqlDrConn.Open();
                SqlCommand SqlCmd = new SqlCommand(StrSql, SqlDrConn);
                SqlDataReader SqlDr = SqlCmd.ExecuteReader();
                if (SqlDr.HasRows)
                {
                    DataTable dt = new DataTable();
                    //读取SqlDataReader里的内容
                    dt.Load(SqlDr);
                    //关闭对象和连接
                    SqlDr.Close();
                    SqlDrConn.Close();                    
                    return dt;
                }
                return null;
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);          
                return null;
            }
            finally
            {        
                SqlDrConn.Close();
            }
        }
    }

通过调用SqlDrConn.Open()方法打开连接,这时候连接池就会初始化并建立设定的最小连接数。想更清楚了解到连接池的 状况可以通过SQL的查询分析器执行存储过程sp_Who,它会列出当前的数据库进程,查看loginname、dbname可以区分用户的连接信息,但 要注意的是登录查询分析器本身会使用两个连接,所以最好用另一个用户名登录查询分析器。使用此方法还有一个麻烦地方就是要经常按“执行查询”以更新进程信 息。还有另一种方法个人认为较好的,通过控制面板→管理工具→性能,右击添加计算器,性能对象选择 SQlServer:GeneralStatistics(常规统计)然后计算器选择UserConnections(用户连接)最后按“添加”就可以实 时查看当前连接数。

到了这里,连接池已经实现了,但问题往往会出现在运行过程中。如连接池的连接数满 了该怎样处理?在这里我们应该合理设置连接字符串中的ConnectTimeout属性和ConnectionLifetime属性(上面有解释)延长等 待时间,尽可能地在每次使用完连接之后调用Close方法关闭连接。但从中也有没法避免的,当连接数满了并且申请连接的时间超过设置连接等待的时间时,程 序将会引发InvalidOperationExceptio异常,我们可以通过捕获此异常向用户界面提示“系统正忙,请稍后再连接……”之类的信息来缓 解这种情况。此外,也有另一种方法来解决这种情况,就是利用ADO.NET2.0新特性“异步进程”,对数据库进行异步操作,确保连接能够及时调用 Close方法关闭连接,这样能大大减少正在使用的连接数。

使用方法:在连接字符串中加上AsynchronousProcessing=true表示使用异步处理操作。

当应用程序不再需要用到连接池的时候可以使用ClearPool或ClearAllPools方法清空连接池也可作重置连接池使用,方法如下:

SqlConnection.ClearPool(SqlConnectionconnection)清空关联的连接池

SqlConnection.ClearAllPools()清空所有连接池

调用上述方法,如果连接正在使用,连接池会做相应标记,等连接关闭时自动烧毁。

小结C#数据库连接池

优点:当数据库操作和访问频繁的时候,减少创建连接和打开连接所耗的时间,提升数据库服务器的性能。

缺点:数据库连接池中可能存在着多个没有被使用的连接一直连接着数据库,这意味着资源的浪费。

以上就是c# 连接池的设置与使用的详细内容,更多关于c# 连接池的资料请关注我们其它相关文章!

(0)

相关推荐

  • C#字符串内存分配与驻留池学习分享

    刚开始学习C#的时候,就听说CLR对于String类有一种特别的内存管理机制:有时候,明明声明了两个String类的对象,但是他们偏偏却指向同一个实例.如下: 复制代码 代码如下: String s1 ="Hello";String s2 ="Hello";                       //s2和s1的实际值都是Hellobool same = (object) s1 == (object) s2;//这里比较s1.s2是否引用了同一个对象实例//所

  • C#实现线程池的简单示例

    本文以实例演示了C#线程池的简单实现方法.程序中定义了一个对象类,用以包装参数,实现多个参数的传递.成员属性包括两个输入参数和一个输出参数.代码简单易懂,备有注释便于理解. 具体实现代码如下: using System; using System.Threading; //定义对象类,用以包装参数,实现多个参数的传递 class Packet { //成员属性包括两个输入参数和一个输出参数 protected internal String inval1; protected internal

  • C#线程池用法详细介绍

    介绍 .NET Framework提供了包含ThreadPool类的System.Threading 空间,这是一个可直接访问的静态类,该类对线程池是必不可少的.它是公共"线程池"设计样式的实现.对于后台运行许多各不相同的任务是有用的.对于单个的后台线种而言有更好的选项. 线程的最大数量.这是完全无须知道的.在.NET中ThreadPool的所有要点是它自己在内部管理线程池中线程.多核机器将比以往的机器有更多的线程.微软如此陈述"线程池通常有一个线程的最大数量,如果所有的线程

  • 浅谈C#中的string驻留池

    昨天看群里在讨论C#中的string驻留池,炒的火热,几轮下来理论一堆堆,但是在证据提供上都比较尴尬.虽然这东西很基础,但比较好的回答也不是那么容易,这篇我就以我能力范围之内跟大家分享一下 一:无处不在的池 开发这么多年,相信大家对'池' 这个概念都耳熟能详了,连接池,线程池,对象池,还有这里的驻留池,池的存在就是为了复用为了共享,独乐乐不如众乐乐,毕竟一个字符串的生成和销毁既浪费空间又浪费时间,还不如先养着. 1. 说说现象 通常我们臆想中是这么认为的,定义几个字符串变量,堆上就会分配几个st

  • C#之CLR内存字符串常量池(string)

    C#中的string是比特殊的类,说引用类型,但不存在堆里面,而且String str=new String("HelloWorld")这样的重装也说没有的. 我们先来看一个方法: class Program { static void Main(string[] args) { String s = "HelloWorld"; Console.WriteLine(s); } } 然后我们用ildasm.exe工具把它生成IL语言来看一看它里面是怎么玩的: .met

  • C#多线程ThreadPool线程池详解

    简单说明一下: 线程池可以看做容纳线程的容器:一个应用程序最多只能有一个线程池:ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池: 每排入一个工作函数,就相当于请求创建一个线程: 线程池的作用: 1.线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率. 2.如果一个线程的时间非常长,就没必要用线程池了(不是不能作长时间操作,而是不宜.),况且我们还不能控制线程池中线程的开始.挂起.和

  • C#实现控制线程池最大数并发线程

    1. 实验目的: 使用线程池的时候,有时候需要考虑服务器的最大线程数目和程序最快执行所有业务逻辑的取舍. 并非逻辑线程越多也好,而且新的逻辑线程必须会在线程池的等待队列中等待 ,直到线程池中工作的线程执行完毕, 才会有系统线程取出等待队列中的逻辑线程,进行CPU运算. 2.  解决问题: <a>如果不考虑服务器实际可支持的最大并行线程个数,程序不停往线程池申请新的逻辑线程,这个时候我们可以发现CPU的使用率会不断飙升,并且内存.网络带宽占用也会随着逻辑线程在CPU队列中堆积,而不断增大. &l

  • c#实现用SQL池,多线程定时批量执行SQL语句的方法

    在实际项目开发中,业务逻辑层的处理速度往往很快,特别是在开发Socket通信服务的时候,网络传输很快,但是一旦加上数据库操作,性能一落千丈,数据库操作的效率往往成为一个系统整体性能的瓶颈.面对这问题,我们怎么办呢?好,下面我就为大家介绍一种方法:构建SQL池,分离业务逻辑层和数据访问层,让业务逻辑层从低效的数据库操作解脱,以提高系统整体性能. (一)SQL池 SQL池是SQL容器,用于存放业务逻辑层抛过来的SQL语句.SQL池主要提供以下几种方法: 1)internal string Pop()

  • C#字体池技术实现代码详解

    字体池的应用,主要是为了解决字体不断创建导致句柄泄漏/内存泄漏的问题,这个问题在Android上也同样存在. 经测试,C# WinForm原生控件不存在字体问题,但是使用的第三方控件Dev 14.1就存在这样的问题. 所以参照线程池思路,想到了使用字体池的方式,使系统中的字体统一为一个对象,经测试,有效解决了泄漏问题. 字体池代码: /// <summary> /// 字体缓存类 /// </summary> public static class FontStatic { ///

  • C#操作IIS程序池及站点的创建配置实现代码

    首先要对Microsoft.Web.Administration进行引用,它主要是用来操作IIS7: using System.DirectoryServices;using Microsoft.Web.Administration; 1:首先是对本版IIS的版本进行配置: 复制代码 代码如下: DirectoryEntry getEntity = new DirectoryEntry("IIS://localhost/W3SVC/INFO");            string V

随机推荐