调用示例:
 

        var tran = ThriftPool.Instance().BorrowInstance();
TProtocol protocol = new TBinaryProtocol(tran);
var client = new xxxx(protocol); //xxxx为生成的thrift代理类的Client对象
var ret = client.TestMethod(parameters); //TestMethod为业务方法名称
ThriftPool.Instance().ReturnInstance(tran);
return ret;
 
配置信息类:
    internal class ThriftConfig
{
#region 单例入口 private static ThriftConfig instance = null;
private static object objLock = new object();
public static ThriftConfig Instance()
{
if (instance == null)
{
lock (objLock)
{
if (instance == null)
{
instance = new ThriftConfig();
}
}
}
return instance;
} #endregion #region 私有构造函数 private ThriftConfig()
{
Host = ConfigHelper.GetAppSettingValue("ESHost");
Port = ConfigHelper.GetAppSettingInt32Value("ESPort");
Encode = Encoding.UTF8;
Timeout = 3000;
MaxActive = ConfigHelper.GetAppSettingInt32Value("ESMaxActiveConnectionCount");
MaxIdle = ConfigHelper.GetAppSettingInt32Value("ESMaxIdleConnectionCount");
MinIdle = ConfigHelper.GetAppSettingInt32Value("ESMinIdleConnectionCount");
MaxWait = 5;
} #endregion #region 配置属性定义 public string Host { get; set; } public int Port { get; set; } public Encoding Encode { get; set; } public bool Zipped { get; set; } public int Timeout { get; set; } public int MaxActive { get; set; } public int MaxIdle { get; set; } public int MinIdle { get; set; } public int MaxWait { get; set; }
#endregion }

  

 
 
连接池处理类:
    internal class ThriftPool
{
#region 属性 private ThriftConfig config; /// 对象缓存池
private static Stack<TTransport> objectPool { get; set; }
/// 同步对象
private static AutoResetEvent resetEvent; /// 空闲对象数
private static volatile int idleCount = 0; private static volatile int activeCount = 0; /// 同步对象锁
private static object locker = new object(); #endregion #region 单例入口 private static long testcount = 0;
private static ThriftPool instance = null;
private static object objLock = new object();
public static ThriftPool Instance()
{
if (instance == null)
{
lock (objLock)
{
if (instance == null)
{
instance = new ThriftPool();
}
}
}
return instance;
} #endregion #region 构造函数 private ThriftPool()
{
config = ThriftConfig.Instance();
CreateResetEvent();
CreateThriftPool();
} #endregion #region 公有操作方法 /// 从对象池取出一个对象
public TTransport BorrowInstance()
{
lock (locker)
{
//Zkx.Infrastruction.Logger.Log.DebugFormat("借前对象池个数:{0},空闲个数:{1}", objectPool.Count(), idleCount);
TTransport transport;
//对象池无空闲对象 if (idleCount == 0)
{
//对象池已已创建对象数达上限
if (activeCount >= config.MaxActive)
{
//Console.WriteLine("waiting..." + activeCount);
resetEvent.WaitOne();
}
else
{
PushObject(CreateInstance());
}
}
transport = objectPool.Pop();
//Console.WriteLine("Pop 对象..." + transport.IsOpen); //空闲对象数小于最小空闲数,添加一个对象到对象池(已创建数不能超标)
if (--idleCount < config.MinIdle && activeCount < config.MaxActive)
{
PushObject(CreateInstance());
} ValidateInstance(transport);
//Console.WriteLine("借出......对象池个数:{0},空闲个数:{1}," + testcount, objectPool.Count(), idleCount);
return transport;
}
} /// 归还一个对象
/// <param name="instance"></param>
public void ReturnInstance(TTransport instance)
{
lock (locker)
{
// Console.WriteLine("Push 对象..." + instance.IsOpen); //空闲对象数达到上限,不再返回线程池,直接销毁
if (idleCount == config.MaxIdle)
{
DestoryInstance(instance);
}
else
{
ValidateInstance(instance);
PushObject(instance);
//发通知信号,有对象归还到对象池
resetEvent.Set();
//Console.WriteLine("归还...");
}
}
}
#endregion #region 私有方法 /// 创建线程同步对象
private void CreateResetEvent()
{
lock (locker)
{
if (resetEvent == null)
{
resetEvent = new AutoResetEvent(false);
}
}
} /// 创建对象池
private void CreateThriftPool()
{
lock (locker)
{
if (objectPool == null)
{
objectPool = new Stack<TTransport>();
}
}
} /// 添加对象到对象池
private void PushObject(TTransport transport)
{
objectPool.Push(transport);
idleCount++;
} /// 创建一个对象
private TTransport CreateInstance()
{
activeCount++;
var objsocket = new TSocket(config.Host, config.Port);
objsocket.Timeout = 5000;
TTransport transport = objsocket; transport.Open();
//Console.WriteLine("创建对象..." + activeCount);
return transport;
} /// 校验对象
private void ValidateInstance(TTransport instance)
{
if (!instance.IsOpen)
{
//Console.WriteLine("校验_重新打开...");
instance.Open();
}
} /// 销毁对象
private void DestoryInstance(TTransport instance)
{
if (instance.IsOpen)
{
instance.Close();
}
//instance.Flush();
instance.Dispose();
activeCount--;
//Console.WriteLine("销毁...");
} #endregion
}

  

 

thrift - C#(CSharp)客户端连接池(ConnectionPool)的更多相关文章

  1. 由浅入深了解Thrift之客户端连接池化续

    前文<由浅入深了解Thrift之客户端连接池化>中我们已经实现了服务调用端 连接的池化,实现的过于简陋,离实际的项目运用还很遥远.本文将在进一步改造,主要是两方面:1.服务端如何注册多个服 ...

  2. Redis客户端连接池

    使用场景 对于一些大对象,或者初始化过程较长的可复用的对象,我们如果每次都new对象出来,那么意味着会耗费大量的时间. 我们可以将这些对象缓存起来,当接口调用完毕后,不是销毁对象,当下次使用的时候,直 ...

  3. 由浅入深了解Thrift之客户端连接池化

    一.问题描述 在上一篇<由浅入深了解Thrift之服务模型和序列化机制>文章中,我们已经了解了thrift的基本架构和网络服务模型的优缺点.如今的互联网圈中,RPC服务化的思想如火如荼.我 ...

  4. Swoole2.0协程客户端连接池的实现

    Swoole2.0官方默认的实例是短连接的,在请求处理完毕后就会切断redis或mysql的连接.实际项目可以使用连接池实现复用. 实现原理也很简单,使用SplQueue,在请求到来时判断资源队列中是 ...

  5. redis客户端连接异常

    本文参考:http://mdba.cn/2015/04/02/redistwemproxy-%e5%ae%a2%e6%88%b7%e7%ab%af%e8%bf%9e%e6%8e%a5%e5%bc%82 ...

  6. [20171106]配置客户端连接注意.txt

    [20171106]配置客户端连接注意.txt --//在配置客户端连接时一般建议使用Net Manager工具,windows下调用执行Net Manager.--//linux下执行 netmgr ...

  7. QTcpServer实现多客户端连接

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QTcpServer实现多客户端连接     本文地址:https://www.techiel ...

  8. 一个I/O线程可以并发处理N个客户端连接和读写操作 I/O复用模型 基于Buf操作NIO可以读取任意位置的数据 Channel中读取数据到Buffer中或将数据 Buffer 中写入到 Channel 事件驱动消息通知观察者模式

    Tomcat那些事儿 https://mp.weixin.qq.com/s?__biz=MzI3MTEwODc5Ng==&mid=2650860016&idx=2&sn=549 ...

  9. 高版本->低版本迁移,低版本客户端连接高版本数据库EXP导出报错EXP-00008,ORA-01455,EXP-00000

    生产环境: 源数据库:RHEL + Oracle 11.2.0.3 目标数据库:HP-UX + Oracle 10.2.0.4   需求:迁移部分表  11.2.0.3-->10.2.0.4,若 ...

随机推荐

  1. Oracle 11g XE 与 Oracle SQL Developer 的配置与使用(重制版)

    Oracle 11g XE 与 Oracle SQL Developer 的配置与使用(重制版) 前提概要 项目上需求要适应Oracle数据库,当然这和某EF框架也有关. 因为Oracle 的表名和列 ...

  2. In-Out Parameters inout keyword

    You write an in-out parameter by placing the inout keyword right before a parameter’s type. An in-ou ...

  3. js预览上传图片

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  4. webstorm主题网址

    http://www.phpstorm-themes.com/ http://www.riaway.com/theme.php

  5. Vue学习之路第十八篇:私有过滤器的使用

    1.上篇已经介绍了全局过滤器的使用,“全局”顾名思义就是一次定义处处使用,可以被一个页面里不同的Vue对象所使用,如下代码所示: <body> <div id="app1& ...

  6. AOJ 2224 Save your cats( 最小生成树 )

    链接:传送门 题意:有个女巫把猫全部抓走放在一个由 n 个木桩(xi,yi),m 个篱笆(起点终点木桩的编号)围成的法术领域内,我们必须用圣水才能将篱笆打开,然而圣水非常贵,所以我们尽量想降低花费来解 ...

  7. 学习笔记——ST表

    作用: 给定一个数列 ai O(nlogn) 预处理 O(1) 查询区间最值 实现: 定义f(i,j) 为ai开始,包括ai的连续2^j个元素的最值 下面以最大值为例: f(i,j)表示max{ak} ...

  8. UVA11752 The Super Powers

    /* UVA11752 The Super Powers https://vjudge.net/contest/153365#problem/Y 数论 注意a^n=b要用除法求,并且求得的n比实际大1 ...

  9. hdu 4079简单贪心

    #include<stdio.h> #include<string.h> #define ll __int64 #define N 11000 struct node { in ...

  10. BA--近零能耗示范楼(西门子-中国建筑科学研究院院内)

    中国建筑科学研究院院内的一栋办公楼使用了西门子的全套楼控.节能.消防.远景开关面板技术,每年的能耗为25kwh,远低于国家绿色能源标准.