关于多线程的一个郁闷的问题(100分)

  • 主题发起人 主题发起人 DARKKENLE
  • 开始时间 开始时间
D

DARKKENLE

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大哥,小弟刚写了一个多线程的小东东,不过在运行的时候老是报“尚未调用COINITIALIZA”的错误,我在工程文件已经对COM初始化了
线程代码如下:
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, ExtCtrls, StdCtrls, Grids, DBGrids, ComCtrls,unit3;
type
thread = class(TThread)
private
{ Private declarations }
protected
procedure Execute;
override;
public
constructor create(query:boolean);
end;
var flag:boolean;
TreeView1: TTreeView;
ADOQuery1: TADOQuery;
ADOQuery2: TADOQuery;
ADOQuery3: TADOQuery;
which:String;
implementation
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure thread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
{ thread }
constructor thread.create(query:boolean);
begin
inherited Create(query);
FreeOnTerminate:=true;
end;

procedure init;
var A,i,b,C,D,E:integer;
VAR p1:array of Ttreenode;
VAR P2:ARRAY OF TTREENODE;
VAR P3:ARRAY OF ttREENODE;
VAR NAME:STRING;
VAR P0:TTREENODE;
var sub_num,TELHEAD:String;
begin
if flag=true then
begin
P0:=TREEVIEW1.Items.AddFirst(NIL,'全区');
ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select a.area a from darkken_ye a group by a.area');
adoquery1.Active:=true;
adoquery1.Open;
I:=ADOQuery1.RecordCount;
setlength(p1,i);
for a:=0 to i-1do
begin
NAME:=ADOQuery1.FieldValues['A'];
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Add('select A.DEPT A from darkken_ye a WHERE A.AREA=:NAME GROUP BY A.DEPT');
ADOQuery2.Parameters.ParamByName('name').Value:=name;
adoquery2.Active:=true;
adoquery2.Open;
b:=ADOQuery2.RecordCount;
setlength(p2,b);
P1[a]:=TREEVIEW1.Items.AddChild(p0,NAME);
FOR C:=0 TO B-1do
begin
sub_num:=ADOQuery2.FieldValues['A'];
P2[C]:=TREEVIEW1.Items.AddChild(P1[A],SUB_NUM);
ADOQUERY3.SQL.Clear;
ADOQUERY3.SQL.Add('SELECT A.TEL_HEAD A FROM DARKKEN_YE A WHERE A.AREA=:NAME AND DEPT=:DEPT');
ADOQuery3.Parameters.ParamByName('name').Value:=name;
ADOQuery3.Parameters.ParamByName('DEPT').Value:=sub_num;
adoquery3.Active:=true;
adoquery3.Open;
D:=ADOQUERY3.RecordCount;
SETLENGTH(P3,D);
FOR E:=0 TO D-1do
begin
TELHEAD:=ADOQUERY3.FieldValues['A'];
P3[E]:=TREEVIEW1.Items.AddChild(P2[C],TELHEAD);
ADOQUERY3.Next;
end;
ADOQuery2.Next;
ADOQUERY3.Close;
end;
ADOQuery2.CLOSE;
ADOQuery1.Next;
end;
ADOQuery1.Close;
end;
end;


procedure thread.Execute;
begin
init;
end;

end.
 
个人意见,在线程中申明的控件最好是用create(nil)创建
adoquery1.create(nil),这样可以方便的释放,节省空间。
你的问题可能也是由于这个问题引起的。可以试试!如是,给点!
 
COINITIALIZA是对线程而言的,每个线程都要初始化.
而且要在Execute中执行.
 
bravel--给的答案我试了下,还是没有解决问题啊~
 
1、ADO组件动态创建,用完后释放。
因为ADO组件是不支持多线程的。
2、TreeView添加部分要进行同步。
 
时报平--你的意思是不是ADO用完了以后在DESTORY啊!
TREEVIEW要同步?在INIT()的方法中吗?可以具体的解释下吗?
 
应该是ado与多线程的问题,你在线程中操作ado前加上Coinitialize(nil);操作完后加上 CoUninitialize();释放就可以了,如:
procedure thread.Execute;
begin
Coinitialize(nil);
init;
CoUninitialize();
end;

当然要在uses里包含activex,comobj。应该就没问题了。
 
cuit421--谢谢可以了啊~~小弟学艺不精希望以后多多指教啊~~~分已送上
 
后退
顶部