一段简单的多线程程序,错在哪里? ( 积分: 100 )

  • 主题发起人 主题发起人 canna
  • 开始时间 开始时间
C

canna

Unregistered / Unconfirmed
GUEST, unregistred user!
我的需求是:在form上的2个progressbar, 在执行线程语句
progressbar.create(false,ProgressBar1);
progressbar.create(false,ProgressBar2);
时,同时显示进度。而我下面的程序,却是先显示ProgressBar1进度,
再显示ProgressBar2进度。而且在进度变化过程中,不能进行其他操作。
显然,没有实现多线程。
各位,请帮我看看,错在哪里?
unit Unit2;
interface
uses
Classes, Comctrls;
type
progressbar = class(TThread)
private
{ Private declarations }
probar: TProgressBar;
procedure showprogress;
protected
procedure Execute;
override;
public
constructor create(Suspended: Boolean;
ProgressBar: TProgressBar);
end;

implementation
constructor progressbar.create(Suspended: Boolean;
ProgressBar: TProgressBar);
begin
inherited create(Suspended);
probar:=progressBar;
end;

procedure progressbar.showprogress;
var i: integer;
begin
for i:=0 to 1000000do
Probar.position:=round(i/10000);
end;

procedure progressbar.Execute;
begin
Synchronize(showprogress);
end;

end.
 
我的需求是:在form上的2个progressbar, 在执行线程语句
progressbar.create(false,ProgressBar1);
progressbar.create(false,ProgressBar2);
时,同时显示进度。而我下面的程序,却是先显示ProgressBar1进度,
再显示ProgressBar2进度。而且在进度变化过程中,不能进行其他操作。
显然,没有实现多线程。
各位,请帮我看看,错在哪里?
unit Unit2;
interface
uses
Classes, Comctrls;
type
progressbar = class(TThread)
private
{ Private declarations }
probar: TProgressBar;
procedure showprogress;
protected
procedure Execute;
override;
public
constructor create(Suspended: Boolean;
ProgressBar: TProgressBar);
end;

implementation
constructor progressbar.create(Suspended: Boolean;
ProgressBar: TProgressBar);
begin
inherited create(Suspended);
probar:=progressBar;
end;

procedure progressbar.showprogress;
var i: integer;
begin
for i:=0 to 1000000do
Probar.position:=round(i/10000);
end;

procedure progressbar.Execute;
begin
Synchronize(showprogress);
end;

end.
 
循环不应该在showprogress中啊,这样试一试,在private中声明ip:integer,当然要注意同步线程变量了
procedure progressbar.Execute;
var
i:integer;
begin
for i:=0 to 1000000do
begin
ip:=round(i/10000);
Synchronize(showprogress);
end;
end;
 
type
progressbar = class(TThread)
private
{ Private declarations }
probar: TProgressBar;
posi : integer;
procedure showprogress;
protected
procedure Execute;
override;
public
constructor create(Suspended: Boolean;
ProgressBar: TProgressBar);
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
constructor progressbar.create(Suspended: Boolean;
ProgressBar: TProgressBar);
begin
inherited create(Suspended);
probar:=progressBar;
end;

procedure progressbar.showprogress;
begin
probar.Position := posi;
end;

procedure progressbar.Execute;
var i : integer;
begin
for i:=0 to 10000do
// 1000000 is too slow...
begin
posi := round(i / 100);
// 10000
Synchronize(showprogress);
Sleep(1);
end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var p1,p2 : progressbar;
begin
p1 := progressbar.create(true, progressbar1);
p2 := progressbar.create(true, progressbar2);
p1.Resume ;
p2.Resume ;
end;

end.
 
type
TProgress=class(TThread)
private
FProgressBar:TProgressBar;
FMax,FMin,i:Integer;
protected
procedure Execute;override;
//执行线程的方法
procedure ProgressRun;
public
constructor Create(ProgressBar:TProgressBar;Max,Min:Integer);virtual;
destructor Destroy;override;
end;

THuanXingThread=class(TThread)
private
FMyProgress1,FMyProgress2:TProgress;
protected
procedure Execute;override;
//执行线程的方法
procedure HuanXing;
public
constructor Create(MyProgress1,MyProgress2:TProgress);virtual;
end;

TForm1 = class(TForm)
Button1: TButton;
ProgressBar1: TProgressBar;
ProgressBar2: TProgressBar;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
HuanxingThread:THuanXingThread;
public
{ Public declarations }
Progress1,Progress2:TProgress;
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Progress1:=TProgress.Create(ProgressBar1,2000,1);
Progress2:=TProgress.Create(ProgressBar2,2000,1);
HuanxingThread:=THuanXingThread.Create(Progress1,Progress2);
end;

{ TProgress }
constructor TProgress.Create(ProgressBar:TProgressBar;Max, Min: Integer);
begin
FProgressBar:=ProgressBar;
FMax:=Max;
Fmin:=Min;
FProgressBar.Max:=FMax;
FProgressBar.Position:=FMin;
FreeOnTerminate:=false;
inherited Create(True);
end;

destructor TProgress.Destroy;
begin
FProgressBar.Free;
inherited;
end;

procedure TProgress.Execute;
begin
inherited;
while i<=FMaxdo
Synchronize(ProgressRun);
end;

procedure TProgress.ProgressRun;
begin
FProgressBar.StepBy(1);
Inc(i);
if FProgressBar.Position=FMax then
begin
FProgressBar.Position:=FMin;
i:=FMin;
end;
end;

{ THuanXingThread }
constructor THuanXingThread.Create(MyProgress1,MyProgress2:TProgress);
begin
FreeOnTerminate:=True;
//为True时:VCL自动消除线程对象
inherited Create(false);
// Create()里的参数为False表示立即启动线程,为True表示暂停线程
FMyProgress1:=MyProgress1;
FMyProgress2:=MyProgress2;
end;

procedure THuanXingThread.Execute;
begin
inherited;
Synchronize(HuanXing);
end;

procedure THuanXingThread.HuanXing;
begin
if FMyProgress1<>nil then
if FMyProgress1.Suspended then
FMyProgress1.Resume;
if FMyProgress2<>nil then
if FMyProgress2.Suspended then
FMyProgress2.Resume;
end;

end.

呵呵,正好前几天搞出来的!
 
to lab01:
用上面的方法可以实现多线程。但有个问题,在前一个线程未执行完成时,
再次执行,progressbar会出现闪烁。可能是你说的线程变量同步问题。那如何
用线程同步解决这个问题呢?谢谢!
 
老兄,你把我上面的代码复制过去看看效果先啊!我这段代码是经过测试能达到你的效果的!
 
关注,哪天复制过去试试看~~~
 
to qingwen07:
好,研究一下你的代码
 
to qingwen07:
执行TForm1.Button1Click时,有abstract error异常
另外,procedure Timer1Timer(Sender: TObject);是没有用的,对吗?编码中没有
 
对,procedure Timer1Timer(Sender: TObject);是没用的.
怎么会有错,我这都一点问题都没有啊!?我再帖一份你看看吧!
type
TProgress=class(TThread)
private
FProgressBar:TProgressBar;
FMax,FMin,i:Integer;
protected
procedure Execute;override;
//执行线程的方法
procedure ProgressRun;
public
constructor Create(ProgressBar:TProgressBar;Max,Min:Integer);virtual;
destructor Destroy;override;
end;

THuanXingThread=class(TThread)
private
FMyProgress1,FMyProgress2:TProgress;
protected
procedure Execute;override;
//执行线程的方法
procedure HuanXing;
public
constructor Create(MyProgress1,MyProgress2:TProgress);virtual;
end;

TForm1 = class(TForm)
Button1: TButton;
ProgressBar1: TProgressBar;
ProgressBar2: TProgressBar;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
HuanxingThread:THuanXingThread;
public
{ Public declarations }
Progress1,Progress2:TProgress;
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Progress1:=TProgress.Create(ProgressBar1,2000,1);
Progress2:=TProgress.Create(ProgressBar2,2000,1);
HuanxingThread:=THuanXingThread.Create(Progress1,Progress2);
end;

{ TProgress }
constructor TProgress.Create(ProgressBar:TProgressBar;Max, Min: Integer);
begin
FProgressBar:=ProgressBar;
FMax:=Max;
Fmin:=Min;
FProgressBar.Max:=FMax;
FProgressBar.Position:=FMin;
FreeOnTerminate:=false;
inherited Create(True);
end;

destructor TProgress.Destroy;
begin
FProgressBar.Free;
inherited;
end;

procedure TProgress.Execute;
begin
inherited;
while i<=FMaxdo
Synchronize(ProgressRun);
end;

procedure TProgress.ProgressRun;
begin
FProgressBar.StepBy(1);
Inc(i);
if FProgressBar.Position=FMax then
begin
FProgressBar.Position:=FMin;
i:=FMin;
end;
end;

{ THuanXingThread }
constructor THuanXingThread.Create(MyProgress1,MyProgress2:TProgress);
begin
FreeOnTerminate:=True;
//为True时:VCL自动消除线程对象
inherited Create(false);
// Create()里的参数为False表示立即启动线程,为True表示暂停线程
FMyProgress1:=MyProgress1;
FMyProgress2:=MyProgress2;
end;

procedure THuanXingThread.Execute;
begin
inherited;
Synchronize(HuanXing);
end;

procedure THuanXingThread.HuanXing;
begin
if FMyProgress1<>nil then
if FMyProgress1.Suspended then
FMyProgress1.Resume;
if FMyProgress2<>nil then
if FMyProgress2.Suspended then
FMyProgress2.Resume;
end;

end.
 
to qingwen07:
再次测试你的编码,仍然有Abstract Error异常
我叙述一下测试过程:
delphi 5,/file/new application,
生成form1和unit1,
在form1上加入button1、progressbar1、progressbar2控件;
在unit1中贴入你的编码,贴入后整个unit1如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
//此后为你的编码 ......
当运行该程序,执行button1click时,出现Abstract Error异常。
 
Synchronize(
函数的作用是把多线程变成单线程来做,
所有的事情都让主线程来做
所以,真正的多线程代码,是不能调用这个方法来实现的
 
不是吧,我这用DELPHI7一点问题都没有啊,我晕了,搞不懂为啥了....还望各位高手说一下啊.....
 
to qingwen07:
我用的是delphi5
 
Delphi5我是真的没测试过啊...那就麻烦各位看看问题出在哪了啊....
 
同意 lab01 说的,还要再加一句 sleep(0) ,用于把优先权暂时交给别的线程
procedure progressbar.Execute;
var
i:integer;
begin
for i:=0 to 1000000do
begin
ip:=round(i/10000);
Synchronize(showprogress);
[red]sleep(0);[/red]
end;
end;
 
inherited create(Suspended);
表示生成一个挂起的线程
你得激活它才行
 
你看看D7的DEMO,不处行了
这么简单的事,比DEMO还要简单的处理过程
 
后退
顶部