to
roman!
以下是你貼出來的代碼﹕
使用TCriticalSection就可以做到。
下面是我的连接池的代码,我比较简单,还没有做计时释放的工作。
constructor TConnectionPools.Create;
begin
FConnList := TList.Create;
FCriticalSection := TCriticalSection.Create;
FTimeout := 5000;
FMaxCount := 15;
FSemaphore := CreateSemaphore(nil, FMaxCount, FMaxCount, nil);
end;
function TConnectionPools.CreateNewInstance: TADOConnection;
var
p: PRemoteConnection;
begin
Result := nil;
FCriticalSection.Enter;
try
New(p);
p.Connection := TADOConnection.Create(nil);
p.Connection.ConnectionString := ConnectionString;
p.Connection.LoginPrompt := False;
try
p.Connection.Open(DataBaseUser,DataBasePass);
except
p.Connection.Free;
Dispose(p);
Exit;
end;
p.InUse := True;
FConnList.Add(p);
Result := p.Connection;
finally
FCriticalSection.Leave;
end;
end;
destructor TConnectionPools.Destroy;
var
i: Integer;
begin
FCriticalSection.Free;
for i := 0 to FConnList.Count - 1 do
begin
PRemoteConnection(FConnList
).Connection.Free;
Dispose(FConnList);
end;
FConnList.Free;
CloseHandle(FSemaphore);
inherited Destroy;
end;
function TConnectionPools.GetLock(Index: Integer): Boolean;
begin
FCriticalSection.Enter;
try
Result := not PRemoteConnection(FConnList[Index]).InUse;
if Result then
PRemoteConnection(FConnList[Index]).InUse := True;
finally
FCriticalSection.Leave;
end;
end;
function TConnectionPools.LockConnection: TADOConnection;
var
i: Integer;
begin
Result := nil;
if WaitForSingleObject(FSemaphore, Timeout) = WAIT_FAILED then
raise Exception.Create('服务器忙,请稍候再试');
for i := 0 to FConnList.Count - 1 do
begin
if GetLock(i) then
begin
Result := PRemoteConnection(FConnList).Connection;
Exit;
end;
end;
if FConnList.Count < MaxCount then
Result := CreateNewInstance;
if Result = nil then { This shouldn't happen because of the sempahore locks }
raise Exception.Create('Unable to lock Connection');
end;
procedure TConnectionPools.ReleaseLock(Index: Integer;
var Value: TADOConnection);
begin
FCriticalSection.Enter;
try
PRemoteConnection(FConnList[Index]).InUse := False;
//Value := nil;
ReleaseSemaphore(FSemaphore, 1, nil);
finally
FCriticalSection.Leave;
end;
end;
procedure TConnectionPools.SetConnectionString(const Value: string);
begin
FConnectionString := Value;
end;
procedure TConnectionPools.SetDataBasePass(const Value: string);
begin
FDataBasePass := Value;
end;
procedure TConnectionPools.SetDataBaseUser(const Value: string);
begin
FDataBaseUser := Value;
end;
procedure TConnectionPools.UnlockConnection(var Value: TADOConnection);
var
i: Integer;
begin
for i := 0 to FConnList.Count - 1 do
begin
if Value = PRemoteConnection(FConnList).Connection then
begin
ReleaseLock(i, Value);
break;
end;
end;
end;
initialization
ConnectionPools := TConnectionPools.Create;
finalization
ConnectionPools.Free;
end.
我本來是初學三層﹐只是現在越搞越不明白﹐這個池是一個什么樣的概念﹖
你所貼出的代碼太今我大開眼界了﹐結果我找了一下delphi的demo﹐可是你
卻全是搬的那個demo﹐并非出自你手﹗那你對池究竟是怎樣想的﹖你對他的認識有多深﹖你是怎樣理解的﹖
還有﹐我希望這個貼子最好重新再開一貼﹐僂主請三思而行﹐因為這個問題已不再是二層與三層的討論了﹐而是未來發展方向的討倫了﹗