泛型实现的对象池

http://www.cnblogs.com/hnxxcxg/archive/2012/02/20/2360649.html

泛型实现的对象池

数据集对象池

unit ServerMethodsUnit1;

interface

uses
  SysUtils, Classes, DSServer, DB, Generics.Collections, DSService, Provider,
  ADODB;

type
  TServerMethods1 = class(TDSServerModule)
    procedure DSServerModuleCreate(Sender: TObject);
  private
    { Private declarations }
    ListofQuery : TDictionary<Integer,Tadoquery>;
    ListofProvider : TDictionary<Integer,Tdatasetprovider>;
    function _GetQuery(asql: string; exeNo: Integer) : Tadoquery;
    function _GetPrv(sql: string; exeNo: Integer) : Tdatasetprovider;
  public
    { Public declarations }
    function GetProviderName(sql: string; exeNo: Integer): string;
  end;

implementation

{$R *.dfm}

uses StrUtils, DSServerContainer, uConst;

procedure TServerMethods1.DSServerModuleCreate(Sender: TObject);
begin
  Listofquery := TDictionary<Integer, Tadoquery>.Create;
  Listofprovider := TDictionary<Integer, Tdatasetprovider>.Create;
end;

function TServerMethods1._GetPrv(sql: string; exeNo: Integer): Tdatasetprovider;
var
  dbprv : Tdatasetprovider;
begin
  if ListofProvider.ContainsKey(exeNo) then
     Result := ListofProvider[exeNo]
  else
  begin
    if ListofProvider.Count <= g_MaxPoolSize then
    begin
      dbprv := TDataSetProvider.Create(Self);
      dbprv.Name := 'dsp'+ IntToStr(exeNo);
      dbprv.DataSet := _GetQuery(sql, exeNo);
      ListofProvider.Add(exeNo, dbprv);
      Result := dbprv;
    end;
  end;
end;

function TServerMethods1._GetQuery(asql: string; exeNo: Integer): Tadoquery;
var
  qry : TADOQuery;
begin
  if Listofquery.ContainsKey(exeNo) then
     Result := ListofQuery[exeNo]
  else
  begin
    if ListofQuery.Count <= g_MaxPoolSize then
    begin
      qry := TADOQuery.Create(Self);
      with qry do
      begin
        Connection := ServerContainer1.GetConnection;
        Name := 'qry'+ IntToStr(exeNo);
        close;
        sql.Clear;
        sql.Text := asql;
        open;
      end;
      ListofQuery.Add(exeNo, qry);
      Result := qry;
    end;
  end;
end;


function TServerMethods1.GetProviderName(sql: string; exeNo: Integer): string;
begin
  Result := _GetPrv(sql, exeNo).Name;
end;

end.

 

 

连接池

unit DSServerContainer;

interface

uses
  SysUtils, Classes, 
  DSTCPServerTransport,
  DSServer, DSCommonServer, DSAuth, DB, ADODB, Generics.Collections, DSService,
  DBXDataSnap, DBXCommon, DSHTTPLayer, DBXinterbase, forms;

type
  TServerContainer1 = class(TDataModule)
    DSServer1: TDSServer;
    DSTCPServerTransport1: TDSTCPServerTransport;
    DSServerClass1: TDSServerClass;
    procedure DSServerClass1GetClass(DSServerClass: TDSServerClass;
      var PersistentClass: TPersistentClass);
    procedure DataModuleCreate(Sender: TObject);
    procedure DSServer1Disconnect(DSConnectEventObject: TDSConnectEventObject);
  private
    { Private declarations }
    ListofConnection : TDictionary<Integer,TadoConnection>;
  public
    function GetConnection : TadoConnection;
  end;

var
  ServerContainer1: TServerContainer1;

implementation

uses Windows, ServerMethodsUnit1,uConst;

{$R *.dfm}

procedure TServerContainer1.DataModuleCreate(Sender: TObject);
begin
  ListofConnection := TDictionary<Integer, TadoConnection>.Create;
end;

procedure TServerContainer1.DSServer1Disconnect(
  DSConnectEventObject: TDSConnectEventObject);
begin
  if GetConnection <> nil then
     GetConnection.Close;
end;

procedure TServerContainer1.DSServerClass1GetClass(
  DSServerClass: TDSServerClass; var PersistentClass: TPersistentClass);
begin
  PersistentClass := ServerMethodsUnit1.TServerMethods1;
end;

function TServerContainer1.GetConnection: TadoConnection;
var
  dbconn : TadoConnection;
begin
  if ListofConnection.ContainsKey(TDSSessionManager.GetThreadSession.Id) then
     Result := ListofConnection[TDSSessionManager.GetThreadSession.Id]
  else
  begin
    if ListofConnection.Count <= g_MaxPoolSize then
    begin
      dbconn := TadoConnection.Create(Self);
      dbconn.Name := 'con'+ IntToStr(TDSSessionManager.GetThreadSession.Id);
      dbconn.LoginPrompt := false;
      dbconn.ConnectionString := 'FILE NAME=' + extractfilepath(application.ExeName) + 'connect.udl';
      ListofConnection.Add(TDSSessionManager.GetThreadSession.Id, dbconn);
      Result := dbconn;
    end;
  end;
end;

end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 C# 中,可以通过以下步骤实现高效的对象池: 1. 创建一个泛型对象池类,该类具有一个对象列表和一个空闲对象堆栈。 2. 在对象池类中添加一个“获取对象”方法,该方法从可用对象列表中返回一个对象(如果列表不为空),否则从空闲对象堆栈中返回一个对象(如果堆栈不为空),否则创建一个新对象并返回它。 3. 在对象池类中添加一个“释放对象”方法,该方法将对象添加到空闲对象堆栈中以供未来使用。 4. 使用对象池时,调用“获取对象”方法来获取需要使用的对象,使用完后调用“释放对象”方法将对象返回到池中。 5. 对象池类可以使用锁来确保线程安全,但是使用锁会影响性能。因此,可以考虑使用无锁数据结构,例如ConcurrentBag或ConcurrentStack。 下面是一个简单的对象池类的示例: ```csharp public class ObjectPool<T> where T : new() { private List<T> availableObjects; private ConcurrentStack<T> freeObjects; public ObjectPool(int initialCapacity) { availableObjects = new List<T>(initialCapacity); freeObjects = new ConcurrentStack<T>(); } public T GetObject() { T obj; if (availableObjects.Count > 0) { obj = availableObjects[availableObjects.Count - 1]; availableObjects.RemoveAt(availableObjects.Count - 1); } else if (freeObjects.TryPop(out obj) == false) { obj = new T(); } return obj; } public void ReleaseObject(T obj) { freeObjects.Push(obj); } } ``` 在使用对象池时,可以按照以下方式获取和释放对象: ```csharp ObjectPool<MyObject> objectPool = new ObjectPool<MyObject>(10); MyObject obj = objectPool.GetObject(); // use the object objectPool.ReleaseObject(obj); ``` 这样就可以高效地重用对象,减少内存分配和垃圾回收的开销。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值