紧急求助:用多线程测试多个数据库连接?(200分)

  • 主题发起人 主题发起人 bobo101
  • 开始时间 开始时间
B

bobo101

Unregistered / Unconfirmed
GUEST, unregistred user!
数据库中保存了多个服务器的ip、sid、password、database等字段,需要逐个探测各条记录保存的数据连接是否可连,若逐个测试耗费时间太长,所以我想用多线程来实现,可我是线程编程的菜鸟,请各位大侠帮帮小弟,若能给段简单例程,小弟更是感激不尽!
这几天为此事快憋疯了!

我是在一窗体的主程序中建立的线程,测试数据连结用的是adoconnection
Thrd = class(TThread)
private
{ Private declarations }
FDBInfo: string;
procedure UpdateUI;

protected
procedure Execute;
override;

public
constructor Create(Suspended: Boolean;
DBInfo: string);
end;

var
f_ljqk: Tf_ljqk;
implementation
{$R *.dfm}
constructor Thrd.Create(Suspended: Boolean;
DBInfo: string);
begin
FDBInfo := DBInfo;
end;

procedure Thrd.Execute;
var
ADO: TADOConnection;
begin
//self.FreeOnTerminate:=true;
ADO := TADOConnection.Create(nil);
ADO.Connectionstring := FDBInfo;
ado.CommandTimeout:=10;
ado.ConnectionTimeout:=5;
if ADO.connected then
Synchronize(UpdateUI)
{ Place thread code here }
end;

procedure Thrd.UpdateUI;
begin
//f_ljqk.label1.caption := '数库1成功';
showmessage('数库成功');
end;

procedure Tf_ljqk.FormCreate(Sender: TObject);
var
inifile: TIniFile;
v_Path,dbconstr,v_dbstr: string;
begin
with adoquery1do
begin
while not eofdo
begin
v_dbstr:='Provider=SQLOLEDB.1;Password='+trim(FieldByName('loadpwd').AsString)+';'+
'Persist Security Info=True;User ID='+trim(FieldByName('loadid').AsString)+';Initial Catalog=master'+
';Data Source='+trim(FieldByName('ip').AsString)+';pooling=false';
Thrd.Create(false,v_dbstr);
next;
end;
end;
end;

错误提示 ....THread Error :句柄无效(6)....
哪位大侠能帮我改改吗
 
给你一种另外的想法。多放置几个定时器。每个定时器运行一个独立的测试连接的过程。按照你的时间间隔设置定时器。
 
先好好了解一下多线程的写法吧,另外你这种循环的方式没有用啊,多线程就是采用多个线程同时操作啊,你这种循环的方式不是等于在主线程里面做一个来处理嘛?而且你这个多线程涉及到对共享数据的访问,需要进行控制,先找本delphi的多线程来看看!
 
在线程创建时传入要测试的连接的参数
然后在Execute函数中执行连接
并将结果有消息通知主线程
 
你这分也太好赚了,我不好意思赚
 
如果想根据数据库中的各条记录动态增加线程怎么实现阿?
 
还是鼓励一下撒,毕竟别人才碰多线程啊,但是给他的建议就是先了解一下多线程,要不总是直接贴代码给你,没有用,你这个里面几行代码就搞定了,如果要是急,可以给你贴!但是你要学到东西才好啊!
 
to Mike1234567890
您能具体指点一下吗?
 
to cqwty
我测试程序时,是在传递参数的位置提示THread Error :句柄无效(6),我的确不明白传递参数的地方是什么错误,还请多多指点
 
为什么没有人回答了阿
 
为什么没人帮帮我啊
 
我帮你整一下吧,
首先一个问题,你使用ado必须先初始化,这是第一个问题;
第二个问题是,你传入的字符串是不是正确的。
第三个问题,你线程结束的时候,你必须采用逆过程来对ado进行处理!
 
ado的初始化coinitialize,
线程结束的时候调用UNcoinitialize
 
ado 的初始化中再加入ado.LoginPrompt:=false;,如果不用线程的话,这样做完全正常
传入的字符串,我也是用的非线程模式下ado的连接字符串(只是多加了;pooling=false'),但不知在线程中还需要怎样设置
我在使用完建立的ado后,在Execute最后加上了ado.free,还是不可以阿
 
你单独怎么执行的,其连接字符串可以一样的,多线程和一般的程序没有多少区别的,关键是你传入的参数,还有就是多线程里面使用ado必须加入我说的那两个函数的。当然你创建的对象必须释放,如果不手动释放也可以,多线程会帮你释放,当然这个是设置了freeonterminated为true的时候,否则必须手动释放的!
 
我把注释的//self.FreeOnTerminate:=true;恢复了
但我从来没有使用过您说的coinitialize和UNcoinitialize两个函数,您能告诉我怎样使用吗?如果我传入的字符串有误,您能帮忙修改一下吗?
谢谢您了!
 
我找寻资料后将程序改成如下所示还是提示 ....THread Error :句柄无效(6)....
uses ......, activex;
......
procedure Thrd.Execute;
var
ADO: TADOConnection;
v_constr1:string;
begin
self.FreeOnTerminate:=true;
CoInitialize(nil);
ADO := TADOConnection.Create(nil);
ADO.Connectionstring := FDBInfo;
ado.LoginPrompt:=false;
ado.CommandTimeout:=5;
ado.ConnectionTimeout:=5;

if ADO.connected then
Synchronize(UpdateUI);
ado.Free;
CoUninitialize;
end;

谁能帮帮我啊
 
bobo101(bobo101) ( ) 信誉:92 2006-8-11 22:21:05 得分: 0



问题解决了,现把主要代码贴出来,以供像我这样的菜鸟学习
unit U_ljqk;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, Grids, DB, ADODB, inifiles, Menus, Syncobjs, activex;
type
Tf_ljqk = class(TForm)
。。。。。。。。。。
private
{ Private declarations }
public
{ Public declarations }
end;

Thrd = class(TThread)
private
{ Private declarations }
FDBInfo: string;

procedure UpdateUI;

procedure UpdateUX;

protected
procedure Execute;
override;


public
end;


var
f_ljqk: Tf_ljqk;


implementation

{$R *.dfm}

procedure Thrd.Execute;

var
ADO: TADOConnection;

begin

self.FreeOnTerminate:=true;
CoInitialize(nil);
ADO := TADOConnection.Create(nil);

ADO.Connectionstring := FDBInfo;

ado.CommandTimeout:=10;

ado.ConnectionTimeout:=5;
ado.LoginPrompt:=false;
try
ado.Open;
except
Synchronize(UpdateUX);
end;

if ADO.connected then

Synchronize(UpdateUI)
else
Synchronize(UpdateUX);
ado.Free;
CoUninitialize;


end;


procedure Thrd.UpdateUI;

begin

f_ljqk.label1.caption := '数库1成功';

end;

procedure Thrd.UpdateUX;

begin

f_ljqk.label1.caption := '数库1失败';

end;



procedure Tf_ljqk.FormCreate(Sender: TObject);

var
v_dbstr: string;

begin

with adoquery1 do

begin

while not eof do

begin

v_dbstr:='Provider=SQLOLEDB.1;Password='+trim(FieldByName('loadpwd').AsString)+';'+ 'Persist Security Info=True;User ID='+trim(FieldByName('loadid').AsString)+';Initial Catalog=master'+';Data Source='+trim(FieldByName('ip').AsString);

new(myThrd);
myThrd^ := Thrd.Create(True);
myThrd^.FreeOnTerminate := True;
myThrd^.FDBInfo := v_dbstr;
myThrd^.Resume;

next;

end;

end;

end;
 
后退
顶部