关于线程的问题?
大家好,我在FORM上放两个PROGRESSBAR ,目的想让程序执行时,两个进度条同时前进,同时显示,用了线程的SYNCHRONIZE,可是依然是一个一个显示,不知哪位能帮一下.谢谢,源代码如下.
FORM上只有三个BUTTON,两个PROGRESSBAR.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;
type
TForm1 = class(TForm)
pb1: TProgressBar;
pb2: TProgressBar;
Button1: TButton;
Button2: TButton;
start: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure startClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
tpbthread = class(tthread)
private
{}
protected
procedure execute; override;
procedure startpb1;
procedure startpb2;
end;
var
Form1: TForm1;
pbthread: tpbthread;
implementation
{$R *.dfm}
{ tpbthread }
procedure tpbthread.execute;
begin
inherited;
//这个地方想让两个进度条同时显示,可是结果是先显示第一个进度条,
//再显示第二个进度条.
//有什么办法能让两个进度条让用户看上去是同时显示的吗?
synchronize(startpb1);
synchronize(startpb2);
end;
//BUTTON1执行第一个进度条
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
pb1.Position := 0;
pb1.Smooth := true;
pb1.Min := 0;
pb1.Max := 10;
for I := pb1.Min to pb1.max do // Iterate
begin
pb1.Position := i;
end; // for
end;
//BUTTON2 执行第二个进度条
procedure TForm1.Button2Click(Sender: TObject);
var
i: integer;
begin
pb2.Position := 0;
pb2.Smooth := true;
pb2.Min := 0;
pb2.Max := 10;
for I := pb2.Min to pb2.max do // Iterate
begin
pb2.Position := i;
end; // for
end;
//此按钮执行线程
procedure TForm1.startClick(Sender: TObject);
begin
pbthread := tpbthread.Create(true);
pbthread.Resume;
end;
//线程的其中一个方法,执行第一个进度条
procedure tpbthread.startpb1;
begin
form1.Button1Click(self);
end;
//线程的第二个方法,执行第二个进度条.
procedure tpbthread.startpb2;
begin
form1.button2Click(self);
end;
end.
[解决办法]
synchronize()所说的同步不是同步执行的意思,而是先执行一个在此期间另一个不能执行,线程同步主要是为了防止线程同时进行使共同访问的数据混乱
[解决办法]
所有的界面元素都是在主线程中执行显示的.
在线程中执行循环,然后分别向主窗体发送消息,用POSTMESSAGE,线程循环中用Sleep(0)来让系统进行线程切换.
然后在主窗体收到消息后改变进度条的值.
[解决办法]
刚的代码有点问题,死循環
//线程执行 procedure tpbthread.execute; beginwith Form1 dobeginpb1.Position := 0;pb2.Position := 0;while (pb1.Position < pb1.Max) and (pb2.Position < pb2.Max) dobeginif pb1.Position < pb1.Max thenpb1.Position := pb1.Position + 1;if pb2.Position < pb2.Max thenpb2.Position := pb2.Position + 1;end;end;end;
[解决办法]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls;
Const
WM_PROGRESS_POSTION=WM_USER+1000;
type
TForm1 = class(TForm)
btn_OK: TButton;
pb_One: TProgressBar;
pb_Two: TProgressBar;
procedure btn_OKClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure OnWM_PROGRESS_POSTION(var msg:TMessage);Message WM_PROGRESS_POSTION;
end;
TMyThread=class(TThread)
private
FWinHandle:THandle;
FMax:Integer;
FID:Integer;
public
constructor Create(CreateSuspended: Boolean;AWinHandle:THandle;AID,AMax:Integer);
procedure Execute; override;
published
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TMyThread }
constructor TMyThread.Create(CreateSuspended: Boolean;
AWinHandle: THandle;AID,AMax:Integer);
begin
inherited Create(CreateSuspended);
FWinHandle:=AWinHandle;
FMax:=AMax;
FID:=AID;
end;
procedure TMyThread.Execute;
var
i,L:Integer;
begin
inherited;
L:=FMax-1;
for i:=0 to L do
begin
PostMessage(FWinHandle,WM_PROGRESS_POSTION,FID,i);
Sleep(100);
end;
end;
procedure TForm1.btn_OKClick(Sender: TObject);
begin
TMyThread.Create(False,Self.Handle,1,1000);
TMyThread.Create(False,Self.Handle,2,2000);
end;
procedure TForm1.OnWM_PROGRESS_POSTION(var msg: TMessage);
begin
case msg.WParam of
1:pb_One.Position:=msg.LParam;
2:pb_Two.Position:=msg.LParam;
end;
end;
end.