indy多线程创建ado连接,连接断开后并释放后,sqlserver的连接不释放问题????

xingfuniao 2007-07-30 11:20:33
indy多线程创建ado连接,创建多个连接后,比如10个,发现sqlserver中有10个该数据库的连接,然后我清除几个连接,但发现sqlserver还是10个,并没释放,但当我把10个都Connection都释放后,sqlserver的连接却都释放了,是什么问题??
也就是说sqlserver中保留了最大数量创建的连接,直到这些连接都释放后才全部释放?

我使用的是1个udl连接sqlserver
indy控件名server

type
TSimpleClient = record
id: Cardinal; //系统编号
IP: string; //IP
Port: integer; //端口
LoginTime: string; //登录时间
UpdateTime: string; //更新时间
DataBackTime: Integer; //监控时间, 超时则断开
MYConn: TADOConnection;
MYQuery: tadoquery;
end;
PMyClient = ^TSimpleClient;

//有客户端连接
procedure TfrmShowMain.ServerConnect(AThread: TIdPeerThread);
var
Client: PMyClient;
list: TList;
i: integer;
Ret: DWord;
begin
try
CoInitialize(nil); //
Client := new(PMyClient);
Client.id := AThread.ThreadID;
Client.IP := AThread.Connection.Socket.Binding.PeerIP;
Client.Port := AThread.Connection.Socket.Binding.PeerPort;
Client.LoginTime := formatdatetime('yyyy-mm-dd HH:mm:ss', now);
Client.UpdateTime := formatdatetime('yyyy-mm-dd HH:mm:ss', now);
AThread.Data := Pointer(client);

Client.MYConn := TAdoconnection.create(nil); //创建的连接
Client.MYConn.LoginPrompt := False;
Client.MYConn.KeepConnection := True;
Client.MYConn.ConnectionString := 'FILE NAME=' + ExtractFileDir(application.ExeName) +
'\bjyy.udl';
Client.MYQuery := tadoquery.Create(nil);
Client.MYQuery.Connection := Client.MYConn;
Client.MYConn.Connected := true;
AThread.Connection.WriteLn('Welcome');
except
on E: Exception do
begin
end;
end;
end;

//在某button click

procedure TfrmShowMain.BitBtn3Click(Sender: TObject);
var
Client: PMyClient;
list: TList;
i: integer;
begin
if not server.Active then
exit;
List := Server.Threads.LockList;
try
for i := 0 to List.Count - 1 do
begin
try
Client := Pointer(TIdPeerThread(List.Items[i]).Data);
if Client = nil then
continue;
if inttostr(Client.id) = listview1.Selected.Caption then
begin //发现我要断开的ID
Client.MYQuery.Close;
Client.MYQuery.Free;

Client.MYConn.Connected := false;
freeandnil(Client.MYConn);

TIdPeerThread(List.Items[i]).Connection.Disconnect;
TIdPeerThread(List.Items[i]).Data := nil;
FreeMem(Client);
CoUnInitialize();
exit;
end;
except
on E: Exception do
begin
end;
end;
end;
finally
Server.Threads.UnlockList;
end;
end;

请高人 指点
...全文
277 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
ccdarkness 2007-07-31
  • 打赏
  • 举报
回复
断掉连接的时候线程是否也结束掉?
xingfuniao 2007-07-31
  • 打赏
  • 举报
回复
?
xingfuniao 2007-07-31
  • 打赏
  • 举报
回复
刚测错了.

不过不创建connection好象和创建了一样.就是我关闭某个连接后,sql的进程中并没有减少,一直保持着最大的连接,直到全部连接都断开后,sql进程才没有了.是不是我程序写的有问题
xingfuniao 2007-07-31
  • 打赏
  • 举报
回复
ccdarkness(亲亲我的宝贝) ( ) 信誉:100

我试了,这样如果在excute时,SQLSERVER就创建了连接,但当我连接关闭后,sql的进程中还存在刚才的连接,只有程序退出了,这些连接才断开
ccdarkness 2007-07-31
  • 打赏
  • 举报
回复
你根本就不用创建TAdoconnection
Client.MYQuery通过TAdoconnection连接到数据库,可以直接写
Client.MYQuery.ConnectionString := 'FILE NAME=' + ExtractFileDir(application.ExeName) +
'\bjyy.udl';
xingfuniao 2007-07-31
  • 打赏
  • 举报
回复
创建connection后,在indy的excute中

client.MYConn.BeginTrans;
client.MYQuery.Close;
client.MYQuery.SQL.Text := 'select * from BJYY_D_UpData where
client.MYQuery.Open;
client.MYQuery.Append;
client.MYQuery.FieldByName('ID').AsString :=
....
....
client.MYQuery.Post;
client.MYConn.CommitTrans;



------------------------------------
ccdarkness(亲亲我的宝贝) ( ) 信誉:100 2007-7-30 23:33:55 得分: 0
freeandnil(Client.MYConn);
改成Client.MYConn.free;试一试

------------
以前就是这样写的,也不行.



-----------------------------------
aniugee(阿牛) ( ) 信誉:100 2007-07-31 08:38:06 得分: 0


为什么不让多个线程去连接一个创建过的TAdoconnection呢,请高手分析一下这两种方法的区别!
-------------------------
这样多个连接去连接1个connection可能会有问题吧,具体什么问题高人解答吧:0


pengxuan 2007-07-31
  • 打赏
  • 举报
回复
没看出来在线程里做创建ADOConnection之后要做什么
aniugee 2007-07-31
  • 打赏
  • 举报
回复
为什么不让多个线程去连接一个创建过的TAdoconnection呢,请高手分析一下这两种方法的区别!
xingfuniao 2007-07-31
  • 打赏
  • 举报
回复
TIdPeerThread(List.Items[i]).Connection.Disconnect;
TIdPeerThread(List.Items[i]).Data := nil;

这个就是结束的哦
ccdarkness 2007-07-30
  • 打赏
  • 举报
回复
freeandnil(Client.MYConn);
改成Client.MYConn.free;试一试
使用TIdAntiFreeze对抗“冻结”   Indy使用一个特殊的组件TIdAntiFreeze来透明地解决客户程序用户界面“冻结”的问题。TIdAntiFreeze在Indy内部定时中断对栈的调用,并在中断期间调用Application.ProcessMessages方法处理消息,而外部的Indy调用继续保存阻塞状态,就好像TIdAntiFreeze对象不存在一样。你只要在程序中的任意地方添加一个TIdAntiFreeze对象,就能在客户程序中利用到阻塞式Socket的所有优点而避开它的一些显著缺点。   Indy使用了线程技术   阻塞式Socekt通常都采用线程技术,Indy也是如此。从最底层开始,Indy的设计都是线程化的。因此用Indy创建服务器和客户程序跟在Unix下十分相似,并且Delphi的快速开发环境和Indy对WinSock的良好封装使得应用程序创建更加容易。   Indy服务器模型   一个典型的Unix服务器有一个或多个监听进程,它们不停地监听进入的客户连接请求。对于每一个需要服务的客户,都fork一个新进程来处理该客户的所有事务。这样一个进程只处理一个客户连接,编程就变得十分容易。   Indy服务器工作原理同Unix服务器十分类似,只是Windows不像Unix那样支持fork,而是支持线程,因此Indy服务器为每一个客户连接分配一个线程。   图1显示了Indy服务器的工作原理。Indy服务器组件创建一个同应用程序主线程分离的监听线程来监听客户连接请求,对于接受的每一个客户,都创建一个新的线程来为该客户提供服务,所有与这一客户相关的事务都由该线程来处理。   使用组件TIdThreadMgrPool,Indy还支持线程池。   线程与Indy客户程序   Indy客户端组件并未使用线程。但是在一些高级的客户程序中,程序员可以在自定义的线程中使用Indy客户端组件,以使用户界面更加友好。

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧