请分析一下简单的线程(50分)

  • 主题发起人 主题发起人 ww20000309
  • 开始时间 开始时间
W

ww20000309

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
tmythread=class(tthread)
private
flabel:tlabel;
procedure addcount;
protected
procedure execute;override;
public
constructor create(mylabel:tlabel);virtual;
end;
var
Form1: TForm1;
count:tmythread;
implementation
{$R *.dfm}
procedure tmythread.addcount ;
var
i:integer;
begin
for i:=1 to 1000do
flabel.Caption:=flabel.Caption+inttostr(i);
end;
procedure tmythread.execute ;
begin
addcount;
end;
constructor tmythread.create(mylabel:tlabel);
begin
flabel:=mylabel;
inherited create(true);
freeonterminate:=false;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
count.create(label1);
count.execute ;
end;

end.
 
对不起,你这样的写法好象不大好吧,也可以说是不正确的写法.
VCL组件并不是线程安全的.因此你并不能直接在你的线程中直接操作你的VCL组件,如果你需要
这样做的话,你应该用线程同步方法进行调用.
type TThreadMethod = procedure of object;
procedure Synchronize(Method: TThreadMethod);
procedure tmythread.execute ;
begin
Synchronize(addcount);
end;

 
to proman:
但是,我用ado控件,确能执行。就是将mylabel换成datasource,adoquery.
 
不错,是能运行,可是这是因为你外面没有使用这个控件,否则不出问题是不可能的,而且出了问题
恐怕还不好查.
 
to promat:
我想进行后台的数据库查询。所以想到了线程。因为我很菜,对线程不懂。请大侠帮忙。
不够还可以在加分。
 
各路大侠请帮忙,分不够还可以再加。
 
是本地的还是远程的数据库.
如果是远程数据库,建议采用三层服务器.后来用线程到服务器上查询.
如果是本地的数据库的话.
我想也许你可以把数据访问组件放在线程内部,这样可以避开VCL的多线程问题.进行查询.
 
to proman:
有关于相应问题的资料吗?
我的email:ww20000309@hotmail.com
提供资料便可加分。
 
ADO是线程安全的,所以没有问题。
但很多VCL都是线程不安全的,
具体你可以看看D的帮助。
还有我刚看得D7 DEVELOPERSGUIDE 对
多线程也将的很详细,你可以看看
 
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
tmythread=class(tthread)
private
flabel:tlabel;
procedure addcount;
protected
procedure execute;override;
public
constructor create(mylabel:tlabel);virtual;
end;
var
Form1: TForm1;
count:tmythread;
implementation
{$R *.dfm}
procedure tmythread.addcount ;
var
i:integer;
begin
for i:=1 to 1000do
flabel.Caption:=flabel.Caption+inttostr(i);
end;
procedure tmythread.execute ;
begin
addcount;
end;
constructor tmythread.create(mylabel:tlabel);
begin
flabel:=mylabel;
inherited create(false);//创建线程后立即执行
freeonterminate:=true;//创建线程后立即释放
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
count.create(label1);
end;

end.
 
自己顶一下.
 
你在线程中使用数据库,要当心同步问题,最好能用Synchronize
 
我这里有一个我写线程时的心得,你得跟据你自己的情况做一些调整。有一点是相同的:线程中都用了控件
{ 线程程序手记
一、定义好Create 时需要传入的各种参数,还有需要控制改变显示的控件,如下列中的Lable
二、做三个过程:
1、procedure procedure1(变量1;变量2……);
virtual;
abstract;
此过程没有任何代码,真正的代码是用子线程类的procedure1用override 方式覆盖之
2、procedure procedure2;
此过程没有变量,所有变量将通过下面的过程传给全局变量,此过量所用变量都为全局
变量,用于简化下面过程用Synchronize函数对本过程的调用;
3、procedure Visualprocedure2(变量1;变量2……);
虚拟的过程二
此过程主要是将变量传给全局量,然后用Synchronize方法调用procedure2;
这一步是必须的。保护线程的同时,真正实现多线程。
三、建立新的线程子类,并建立 procedure1 取代主类中的procedure1 过程;
}
unit Unit2;
interface
uses
Classes,Forms,StdCtrls,SysUtils, Gauges ,WinProcs;
type
TestThread = class(TThread)
private
FStep:integer;
FLab:Tlabel;
Fg:TGauge;
FA,FB:integer;
procedure Showlab;
//procedure2;
protected
procedure Execute;
override;
procedure VisualShowLab(a,b:integer);
//Visualprocedure2(变量1;变量2……);
procedure Showcap(a:integer);
virtual;
abstract;
//procedure1(变量1;变量2……);
virtual;
abstract;
public
constructor Create(Suspended:Boolean;Step:integer;lab:Tlabel;TG:TGauge);
end;
TTest1 = class(TestThread)
protected
procedure Showcap(A: Integer);
override;
end;

implementation
constructor TestThread.Create(Suspended:Boolean;Step:integer;lab:Tlabel;TG:TGauge);
begin
inherited Create(Suspended);
FStep:=Step;
FLab:=lab;
FG:=TG;
FreeOnTerminate:=True;
end;

procedure TestThread.Showlab;
begin
Flab.Caption:=inttostr(FA);
FG.Progress:=FG.Progress+1;
end;

procedure TestThread.VisualShowLab(a,b: integer);
begin
FA:=a;
Fb:=b;
Synchronize(Showlab);
end;

procedure TestThread.Execute;
begin
Showcap(FStep);
end;

{ TTest1 }
procedure TTest1.Showcap(A: Integer);
var
i,j,b:integer;
begin
b:=0;
for i:=1 to 1000do
begin
b:=b+a;
VisualShowLab(b,i);
for j:=1 to 100do
Application.ProcessMessages;
if Terminated then
exit;
end;
end;

end.

调用程序:
uses
unit2;
……
Procedure aaa(Sender:Tobject);
……
var
Form1: TForm1;
a,b:TTest1;
int:integer;
implementation
{$R *.DFM}
procedure TForm1.aaa(Sender: Tobject);
begin
int:=Int+1;
if int=2 then
showmessage('线程全部结束!');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
int:=0;
Gauge1.MaxValue:=2000;
Gauge1.Progress:=0;
a:=TTest1.create(false,1,label1,Gauge1);
B:=TTest1.create(false,2,label2,Gauge1);
a.OnTerminate:=aaa;
b.OnTerminate:=aaa;
end;
 
多人接受答案了。
 
后退
顶部