100大元求一个线程(100分)

  • 主题发起人 主题发起人 efarer
  • 开始时间 开始时间
E

efarer

Unregistered / Unconfirmed
GUEST, unregistred user!
求一个显示工作进度的线程,如
ShowProgressBar(参数:预计显示时间);
for j:=1 to 100do
begin
// 业务处理
end;
FreeProgressBar;

说明如下:
函数ShowProgressBar用来创建一个线程,打开一个窗体并显示一个进度条(ProgressBar)
函数FreeProgressBar消毁窗体,结束线程
关键是在我业务处理时能平滑地显示进度条的当前进度
 
用线程消息来处理,告,当前进度.
 
ShowProgressBar(参数:预计显示时间);
以上过程并不需要与主线程通讯,它只是在[gold]规定的时间内能平滑地显示完进度[/gold],
然后调用函数FreeProgressBar消毁窗体,结束线程
 
高手请进啊
 
就是一个需要在线程执行过程中把一些参数反映到进度条上的么?
还有一个就是杀死线程,提前结束?
 
正好昨天有段代码,改了改,试验成功了,你可以看看
代码有点乱
---------
form1
------------------------------------------------
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TestTh= class(TThread)
private
i:integer;
procedure closeForm;
procedure showI();
procedure onTer(sender:tobject);
public
procedure execute;override;
end;

TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
t:TestTh;
fTheF:TForm;
function getForm:TForm;
procedure SetForm(Value:Tform);
public
property F:TForm read getForm write setForm;
end;

var
Form1: TForm1;
implementation
uses Unit2;

{$R *.dfm}
procedure TestTH.execute;
var j:integer;
begin
FreeOnTerminate := true;
onterminate := self.onTer;
{ for j:=0 to 100do
begin
i:=j;
Synchronize(showI);
sleep(1);
end;
}
Synchronize(showi);
while truedo
begin
if terminated then
break;
end;
end;

procedure TestTh.onTer(sender:tobject);
begin
form1.F.Close;
end;
procedure TestTH.closeForm;
begin
if form1.f.Showing then
form1.f.Close;
end;

procedure TestTh.showI();
begin
//form1.Edit1.Text := inttostr(i);
form1.F.Show;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
t:=testth.Create(false);
for i:= 1 to 100000do
begin
edit1.Text := inttostr(i);
application.ProcessMessages;
end;
t.Terminate;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
// TForm2(self.F).ShowModal;
self.t.Terminate;
end;

function TForm1.getForm:TForm;
begin
result:=self.fTheF;
end;

procedure TForm1.SetForm(value:Tform);
begin
self.fTheF:=value;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
self.F := form2;
end;

end.

------------------------------------------------
-----
form2
-----
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ComCtrls;
type
TForm2 = class(TForm)
ProgressBar1: TProgressBar;
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Timer1Timer(Sender: TObject);
begin
if self.ProgressBar1.Position = self.ProgressBar1.Max then
self.ProgressBar1.Position := self.ProgressBar1.Min;
self.ProgressBar1.StepIt;
end;

end.
------------------------------------------------
 
成功了记得结贴
 
// 此线程没有用到线程同步, 因为显示进度窗体为独占
// 如果你要在程序期间创建多个显示进度窗体,请不要用,还要做修改
TDlgThread = class(TThread)
private
FTm: DWord;
// 剩余时间(ms)
protected
procedure Execute;
override;
public
constructor Create(ATm: DWord;
Suspended: Boolean);
end;

var
AForm: TFrmThread;
// 此为你的显示进度窗体我这只有一个progressbar
implementation
{$R *.dfm}
{ ------------------- 线程单元 ------------------ }
constructor TDlgThread.Create(ATm: DWord;
Suspended: Boolean);
begin
FTm := ATm;
inherited Create(Suspended);
end;

procedure TDlgThread.Execute;
var
i: Integer;
begin
for i := 1 to 100do
begin
在此时间为大致估计消耗你的,不是严格准确
Sleep(Trunc(FTm/100));
AForm.pgbTran.Position := i * FTm;
end;
FreeAndNil(AForm);
end;

// 你所要函数
procedure TForm1.ShowProgress(dwTm: DWord);// 毫秒
var
ADlgThread: TDlgThread;
begin
if not Assigned(AForm) then
AForm := TFrmThread.Create(nil);
AForm.Show;
AForm.pgbTran.Max := dwTm * 100;
AForm.pgbTran.Min := dwTm;
AForm.pgbTran.Position := dwTm;
ADlgThread := TDlgThread.Create(dwTm, False);
end;
 
呵,高手很多,让我测试一下,
程序的关键是:如何能平滑地显示进度条,因为业务处理是一个循环,就象:
ShowProgressBar(参数:预计显示时间);
for j:=1 to 100do
begin
// 业务处理
//此间不需要与进度窗通讯,只需要能看到进度条平滑地向前推进
end;
FreeProgressBar;
 
各位高手分照样给,只是问题并没有解决,主要是我举例举错了,并没有for循环,实际上是这样的:
ShowProgressBar(参数:预计显示时间);
//引间进行业务处理,大约需几分种
// 比如:调用一个存储过程,备份目录等,是一个不可分拆的过程
FreeProgressBar;
以上,无法找不到一个好的解决方法能平滑地显示当前业务处理的进度
如果有好的解决方法,我另开贴送分
 
准备再加100分
 
抄的:
type
MyThread = class(TThread)
private
{ Private declarations }
FProgress: Integer;
procedure CreateAndShowProgressWin;
procedure UpdateProgressWin;
procedure FreeProgressWin;
protected
procedure Execute;
override;
end;

implementation
{ MyThread }
procedure MyThread.CreateAndShowProgressWin;
begin
...
end;

procedure UpdateProgressWin;
begin
...
end;

procedure FreeProgressWin;
begin
...
end;

procedure MyThread.Execute;
begin
FProgress := 0;
Synchronize(CreateAndShowProgressWin);
try
for ...
begin
...
Inc(FProgress);
Synchronize(UpdateProgressWin);
end;
finally
Synchronize(FreeProgressWin);
end;
end;
 
可以如下处理:
在线程里:
procedure TThrdProcess.Excute()
var
i : integer;
begin
for i=0 to 要处理的最大记录数do
begin
// 处理一条记录
//...
PostMessage(m_hWnd, m_dwMsg, THREAD_PROCESS, i);
if ( Terminated) then
break;
end
end;
其中 m_hWnd是处理dwMsg的窗口的句柄,
dwMsg是自定义的消息,为WM_USER + 自然数
THREAD_PROCESS 为WPRRAM,说明传送过来的消息是描述处理进度的
i 当前处理到第i条记录
 
关键问题:
比如是调用一个存储过程,数据库的处理约需5分种,引间progressbar就不stepit,界面看了跟死机一样,如何让progressbar能正常显示步进????????
征求:高手高招
 
继续征寻高手.............
 
》界面看了跟死机一样,
我一般发Application.ProcessMessages
另外,为什么
》 ShowProgressBar(参数:预计显示时间);
》 //引间进行业务处理,大约需几分种
》 // 比如:调用一个存储过程,备份目录等,是一个不可分拆的过程
》 FreeProgressBar;
这样呢?
你应该把业务处理放在线程里啊
 
是的,我把业务处理放入线程运行,主线程显示progressbar ,但看上去仍不行,依旧跟死机一样,我觉得这种情况应该很多,谁有同感?
 
准备结贴,就是仍没有好的解决方法,[:(]
 
》我把业务处理放入线程运行,主线程显示progressbar ,但看上去仍不行,依旧跟死机一样
请再提供详细点的信息吧
你的progressbar 是怎么刷新的?
线程是怎么实现的?
 
多谢关注,但问题仍未解决
 
后退
顶部