数据模块池
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.
本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/archive/2012/11/23/2785043.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?