C# mysql 連接池

jopen 8年前發布 | 16K 次閱讀 .NET開發

      該連接池除了基本功能,還多增加了一個管理連接的功能,我看了別人寫的,沒有這個功能,所以臭屁地說這是我這個程序的亮點,哈哈。

      這個管理連接的功能主要是創建了一個后臺線程,然后死循環,不斷檢測連接池中的連接是否空閑已久(比如空閑了10s),如果空閑已久,就把它關了。

      剛學 C# 不久,如果有哪里不對或者需要改進的地方,還望指教。

using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Configuration;

namespace NetBlog.Data
{
    /// <summary>
    /// Mysql 連接池
    /// 單例模式
    /// </summary>
    public class MysqlPool
    {
        /// <summary>
        /// 數據庫配置信息
        /// </summary>
        private static string ConnectinString = "";
        /// <summary>
        /// 連接池中的數據庫連接對象
        /// </summary>
        private List<MySqlConnection> connections = null;
        /// <summary>
        /// 數據庫連接對象的狀態
        /// true 為占用,false 為空閑
        /// </summary>
        private List<bool> status = null;
        /// <summary>
        /// 目前連接對象的總數
        /// </summary>
        private int total = 0;
        /// <summary>
        /// 目前在用的連接對象數量
        /// </summary>
        private int inUseNum = 0;
        private static int minPoolSize = 10;
        private static int maxPoolSize = 100;
        /// <summary>
        /// 連接對象空閑存活時間 100s
        /// </summary>
        private static double activeTime = 10000;
        /// <summary>
        /// 空閑狀態起始時間
        /// </summary>
        private Dictionary<int, double> idleTime = null;
        /// <summary>
        /// 單例
        /// </summary>
        private static MysqlPool pool = null;
        /// <summary>
        /// 連接池創建時間
        /// </summary>
        private DateTime startTime;
        /// <summary>
        /// 管理連接池的線程
        /// </summary>
        private Thread thread = null;

        private MysqlPool()
        {
            this.connections = new List<MySqlConnection>();
            this.status = new List<bool>();
            this.idleTime = new Dictionary<int, double>();
            this.startTime = DateTime.Now;
            // 將線程設置為后臺線程
            // 使得在程序退出后,線程自動結束
            this.thread = new Thread(this.ManagePool)
            {
                Name = "MysqlPoolManagerThread",
                IsBackground = true
            };
            this.thread.Start();
        }

        public static MysqlPool GetInstance()
        {
            lock (typeof(MysqlPool))
            {
                if (pool == null)
                {
                    pool = new MysqlPool();
                }
            }
            return pool;
        }

        public MySqlConnection GetConnection()
        {
            lock (this.connections)
            {
                if (this.inUseNum == this.total)
                {
                    // 連接已占滿
                    return CreateNewConnection();
                }
                else
                {
                    // 有空閑連接
                    for(int i = 0; i< this.status.Count; i++)
                    {
                        if (this.status[i])
                        {
                            continue;
                        }
                        else
                        {
                            this.inUseNum++;
                            this.status[i] = true;
                            this.idleTime.Remove(i);
                            return this.connections[i];
                        }
                    }
                    return null;
                }
            }
        }

        private MySqlConnection CreateNewConnection()
        {
            if (this.total < maxPoolSize)
            {
                MySqlConnection conn = new MySqlConnection(ConnectinString);
                this.connections.Add(conn);
                this.status.Add(true);
                this.total++;
                this.inUseNum++;
                return conn;
            }
            return null;
        }

        /// <summary>
        /// 歸還連接
        /// 在方法結束前調用 conn = null 使用戶是去對連接對象的引用
        /// 避免再次調用連接
        /// </summary>
        /// <param name="conn"></param>
        public void ReleaseConnection(ref MySqlConnection conn)
        {
            if (conn == null)
            {
                return;
            }
            else
            {
                int index = this.connections.IndexOf(conn);
                if (index < 0)
                {
                    conn.Close();
                    conn = null;
                }
                else
                {
                    this.inUseNum--;
                    this.status[index] = false;
                    this.idleTime.Add(index, DateTime.Now.Subtract(this.startTime).TotalMilliseconds);
                    conn = null;
                }
            }
        }

        /// <summary>
        /// 管理連接池
        /// 將長時間處于空閑狀態的連接釋放
        /// </summary>
        private void ManagePool()
        {
            while (true)
            {
                lock (this.connections)
                {
                    // 已刪除連接個數
                    int num = 0;
                    if (this.total-this.inUseNum > minPoolSize)
                    {
                        // 空閑連接大于最小連接池大小
                        // 將多余的空閑連接刪除
                        double mill = DateTime.Now.Subtract(this.startTime).TotalMilliseconds;
                        for (int i = 0; i < this.connections.Count; i++)
                        {
                            double idle = this.idleTime[i];
                            if (mill > idle + activeTime)
                            {
                                int index = i - num;
                                MySqlConnection conn = this.connections[index];
                                lock (conn)
                                {
                                    conn.Close();
                                    this.connections.RemoveAt(index);
                                    this.total--;
                                    this.status.RemoveAt(index);
                                    this.idleTime.Remove(i);
                                }
                                num++;
                            }
                        }
                    }
                }
                Thread.Sleep(500);
            }
        }
    }
}


來自: http://my.oschina.net/u/1995999/blog/592746

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!