数据模块池

unit untDMPool;

interface

uses
Classes, SyncObjs, SysUtils,
DateUtils, untData;

type

PServerObject = ^TServerObject;

TServerObject = record
ServerObject: TdmData;
InUse: Boolean;
end;

TDMPool = class
private
FCriticalSection: TCriticalSection;
FServerObjects: TList;
FPoolSize: integer;

public
constructor Create; overload;
destructor Destroy; override;
function Lock: TdmData;
procedure Unlock(Value: TdmData);
procedure Init;
property PoolSize: integer read FPoolSize write FPoolSize;
end;

var
G_DMPool: TDMPool;

implementation
Uses
untCommonFun;

constructor TDMPool.Create;
begin
FPoolSize := 20;
FServerObjects := TList.Create;
FCriticalSection := TCriticalSection.Create;
end;

destructor TDMPool.Destroy;
begin
while FServerObjects.Count > 0 do
begin
PServerObject(FServerObjects[0])^.ServerObject.Free;
Dispose(PServerObject(FServerObjects[0]));
FServerObjects.Delete(0);
end;
FreeAndNil(FServerObjects);
FreeAndNil(FCriticalSection);
inherited Destroy;
end;

procedure TDMPool.Init;
var
i: integer;
p: PServerObject;
begin
if not Assigned(FServerObjects) then exit;
try
for i := 1 to FPoolSize do
begin
New(p);
if Assigned(p) then
begin
p^.ServerObject := TdmData.Create(nil);
p^.InUse := False;
FServerObjects.Add(p);
end;
end;
except
On E:Exception do
begin
SysLog.WriteLog(e.Message);
Exit;
end;
end;
end;

function TDMPool.Lock: TdmData;
var
i: integer;
bFound: Boolean;
begin
Result := nil;
try
FCriticalSection.Enter;
try
bFound := False;
for i := 0 to FServerObjects.Count - 1 do
begin
if not PServerObject(FServerObjects[i])^.InUse then
begin
PServerObject(FServerObjects[i])^.InUse := True;
Result := PServerObject(FServerObjects[i])^.ServerObject;
bFound := True;
Break;
end;
end;
if (FServerObjects.Count = PoolSize) and (not bFound) then
begin
Result := TdmData.Create(nil);
Result.tag := 5;
end;
finally
FCriticalSection.Leave;
end;
except
on e:Exception do
begin
SysLog.WriteLog(e.Message);
Exit;
end;
end;
end;

procedure TDMPool.Unlock(Value: TdmData);
var
i: integer;
begin
if not Assigned(Value) then
exit;
try
FCriticalSection.Enter;
try
if Value.tag = 5 then
begin
FreeAndNil(Value);
end
else
begin
for i := 0 to FServerObjects.Count - 1 do
begin
if Value = PServerObject(FServerObjects[i])^.ServerObject then
begin
PServerObject(FServerObjects[i])^.InUse := False;
Break;
end;
end;
end;
finally
FCriticalSection.Leave;
end;
except
On E:Exception do
begin
SysLog.WriteLog(e.Message);
Exit;
end;
end;
end;

end.

posted @   delphi中间件  阅读(555)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示