Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Exasol Ado.Net提供程序的自定义连接池_C#_Multithreading_Ado.net_Task Parallel Library_Exasolution - Fatal编程技术网

C# Exasol Ado.Net提供程序的自定义连接池

C# Exasol Ado.Net提供程序的自定义连接池,c#,multithreading,ado.net,task-parallel-library,exasolution,C#,Multithreading,Ado.net,Task Parallel Library,Exasolution,我们使用的是内存数据库Exasol,它确实提供了Ado.Net提供程序,但它似乎缺少了一些重要的功能,如ConnectionPooling,因此每个请求都会创建和销毁连接,这影响了我们的性能,因为我们在AWS上连接到托管数据库。我已经创建了一个简单的连接池,可以调整大小,请建议这是否可以达到目的,或者我需要做更多的事情 请注意,我不是要查看代码,而是要对当前实现中可能缺少的内容进行批判性分析,如果有可用的实现(Nuget,Git),我可以重用它。目前我正在根据大小调整大小,如何根据时间实现相同的

我们使用的是内存数据库
Exasol
,它确实提供了Ado.Net提供程序,但它似乎缺少了一些重要的功能,如
ConnectionPooling
,因此每个请求都会创建和销毁连接,这影响了我们的性能,因为我们在
AWS
上连接到托管数据库。我已经创建了一个简单的
连接池
,可以
调整大小
,请建议这是否可以达到目的,或者我需要做更多的事情

请注意,我不是要查看代码,而是要对当前实现中可能缺少的内容进行批判性分析,如果有可用的实现(Nuget,Git),我可以重用它。目前我正在根据大小调整大小,如何根据时间实现相同的大小,在一定的空闲时间内,将从队列中清除少量资源,从而减少大小

重要细节:

  • 在内部使用
    ConcurrentQueue
    从多个客户端对资源进行线程安全访问
  • 使用
    AutoResetEvent
    等待,并在池为空时发出信号
  • 使用
    TPL
    调整操作的大小,而不停止调用代码,我的理解是,即使在客户端调用返回时,这项工作仍然有效,因为它在
    Threadpool线程上运行

    class ExasolConnectionPool
    {
        /// <summary>
        /// Thread safe queue for storing the connection objects
        /// </summary>
        private ConcurrentQueue<EXAConnection> ExasolConnectionQueue { get; set; }
    
        /// <summary>
        /// Number of connections on the Connection pool
        /// </summary>
        private int _connectionCount;
    
        /// <summary>
        /// Max Pool Size
        /// </summary>
        private int MaxPoolSize { get; set; }
    
        /// <summary>
        /// Min Pool Size
        /// </summary>
        private int MinPoolSize { get; set; }
    
        /// <summary>
        /// Increase in Pool Size
        /// </summary>
        private int IncreasePoolSize { get; set; }
    
        /// <summary>
        /// Decrease in Pool Size
        /// </summary>
        private int DecreasePoolSize { get; set; }
    
        /// <summary>
        /// Connection string for the Connection pool connections
        /// </summary>
        private string ConnectionString { get; set; }
    
        /// <summary>
        /// Auto Reset event for the connection pool
        /// </summary>
        private AutoResetEvent ExasolConnectionPoolAre { get; set; }
    
        /// <summary>
        /// Connection pool specific Lock object
        /// </summary>
        private readonly object lockObject;
    
        /// <summary>
        /// Connection pool constructor
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="poolSize"></param>
        public ExasolConnectionPool(string connectionString, int poolSize = 10)
        {
            // Set the Connection String
            ConnectionString = connectionString;
    
            // Intialize the Connection Queue
            ExasolConnectionQueue = new ConcurrentQueue<EXAConnection>();
    
            // Enqueue initial set of connections
            for (int counter = 0; counter < poolSize; counter++)
            {
                var exaConnection = new EXAConnection {ConnectionString = ConnectionString};
    
                ExasolConnectionQueue.Enqueue(exaConnection);
            }
    
            // Initialize Lock object 
            lockObject = new object();
    
            // Set the Connection queue count
            _connectionCount = poolSize;
    
            // Max pool size
            MaxPoolSize = poolSize;
    
            // Min Pool Size
            MinPoolSize = 2;
    
            IncreasePoolSize = 5;
    
            DecreasePoolSize = 3;
    
            ExasolConnectionPoolAre = new AutoResetEvent(false);
        }
    
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public EXAConnection GetConnection()
        {
            // Return ExaConnection object
            EXAConnection returnConnection;
    
            // Try Dequeue the connection object from the Concurrent Queue
            var validExasolConnection = ExasolConnectionQueue.TryDequeue(out returnConnection);
    
            // If No Valid connection is available, then wait using AutoReset signaling mechanism
            while (!validExasolConnection)
            {
                ExasolConnectionPoolAre.WaitOne();
    
                validExasolConnection = ExasolConnectionQueue.TryDequeue(out returnConnection);
            }
    
            // Thread safe connection count update
            Interlocked.Decrement(ref _connectionCount);
    
            Task.Factory.StartNew(() =>
            {
                lock (lockObject)
                {
                    if (_connectionCount > MinPoolSize) return;
    
                    for (var counter = 0; counter < IncreasePoolSize; counter++)
                    {
                        var exaConnection = new EXAConnection {ConnectionString = ConnectionString};
    
                        ExasolConnectionQueue.Enqueue(exaConnection);
    
                        Interlocked.Increment(ref _connectionCount);
                    }
                }
            });
    
            return (returnConnection);
        }
    
        /// <summary>
        /// 
        /// </summary>
        /// <param name="returnedConnection"></param>
        public void ReturnConnection(EXAConnection returnedConnection)
        {
            ExasolConnectionQueue.Enqueue(returnedConnection);
    
            Interlocked.Increment(ref _connectionCount);
    
            ExasolConnectionPoolAre.Set();
    
            Task.Factory.StartNew(() =>
            {
                lock (lockObject)
                {
                    if (_connectionCount < MaxPoolSize * 1.5) return;
    
                    for (var counter = 0; counter < DecreasePoolSize; counter++)
                    {
                        EXAConnection exaConnection;
    
                        if (ExasolConnectionQueue.TryDequeue(out exaConnection))
                        {
                            exaConnection.Dispose();
    
                            exaConnection = null;
    
                            Interlocked.Decrement(ref _connectionCount);
                        }
                    }
                }
            });
        }
    }
    
    类ExasolConnectionPool
    {
    /// 
    ///用于存储连接对象的线程安全队列
    /// 
    私有ConcurrentQueue ExasolConnectionQueue{get;set;}
    /// 
    ///连接池上的连接数
    /// 
    私人国际连接账户;
    /// 
    ///最大池大小
    /// 
    私有int MaxPoolSize{get;set;}
    /// 
    ///最小池大小
    /// 
    私有int MinPoolSize{get;set;}
    /// 
    ///池大小的增加
    /// 
    private int IncreasePoolSize{get;set;}
    /// 
    ///池大小减少
    /// 
    私有int递减池大小{get;set;}
    /// 
    ///连接池连接的连接字符串
    /// 
    私有字符串连接字符串{get;set;}
    /// 
    ///连接池的自动重置事件
    /// 
    私有自动resetEvent ExasolConnectionPoolAre{get;set;}
    /// 
    ///连接池特定的锁对象
    /// 
    私有只读对象锁对象;
    /// 
    ///连接池构造函数
    /// 
    /// 
    /// 
    公共ExasolConnectionPool(字符串connectionString,int-poolSize=10)
    {
    //设置连接字符串
    ConnectionString=ConnectionString;
    //初始化连接队列
    ExasolConnectionQueue=新的ConcurrentQueue();
    //将初始连接集排队
    对于(int计数器=0;计数器<池大小;计数器++)
    {
    var exaConnection=newexaconnection{ConnectionString=ConnectionString};
    ExasolConnectionQueue.Enqueue(exaConnection);
    }
    //初始化锁对象
    lockObject=新对象();
    //设置连接队列计数
    _connectionCount=池大小;
    //最大池大小
    MaxPoolSize=池大小;
    //最小池大小
    最小池大小=2;
    增加池大小=5;
    减少池大小=3;
    ExasolConnectionPoolAre=新的自动存储事件(false);
    }
    /// 
    /// 
    /// 
    /// 
    公共连接ExageConnection()
    {
    //返回连接对象
    EXAConnection返回连接;
    //尝试从并发队列中退出连接对象
    var validExasolConnection=ExasolConnectionQueue.TryDequeue(out-returnConnection);
    //如果没有可用的有效连接,则使用自动重置信号机制等待
    而(!validExasolConnection)
    {
    ExasolConnectionPoolAre.WaitOne();
    validExasolConnection=ExasolConnectionQueue.TryDequeue(out returnConnection);
    }
    //线程安全连接计数更新
    联锁减量(参考连接计数);
    Task.Factory.StartNew(()=>
    {
    锁定(锁定对象)
    {
    if(_connectionCount>MinPoolSize)返回;
    对于(变量计数器=0;计数器
    {
    锁定(锁定对象)
    {
    if(_connectionCount

  • 您的池的实现很好。我不知道有哪种NuGet实现如此之小,并且对于您的案例来说不会过于复杂。我只想补充一些建议,你可以自己调查

  • 斯蒂芬·克利里(Stephen Cleary)的文章是一篇关于调整逻辑大小的方法的好文章。最重要的是:

    线程“A”将在
    TaskScheduler