怎样通过多线程技术实现TProgressBar进度和数据保存一致?多给点分!(225分)

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

cenghao

Unregistered / Unconfirmed
GUEST, unregistred user!
比如说,数据保存是较为普遍的从内存保存于SQL Server数据库
TProgressBar是置于操作界面上,而保存数据这个操作是某个类(TOneClass)的一个
方法(.SaveToDB)而已,怎么用多线程技术实现?如将TProgressBar也封装同一个
类(TOneClass)则该类与界面结合太重,一个类与界面结合显然是面向对象原则相背离的。
谁能给个好点的代码示例吗?
 
示例代码,仅供具体应用时参照!
首先创建进程:
TExampler := ExampleThread.Create(False);
TExampler.OnTerminate := TBtnClick;
TExampler.FreeOnTerminate := True;
然后进行一个类定义:
Type
ExampleThread = class(TThread)
Public
function showPro(i: byte): integer;
safecall;
procedure savetimeCaption;
private
{ Private declarations }
protected
firstsave, secondsave: real;
datetime: real;
id: integer;
end: LongInt;
procedure Execute;
override;
end;
最后重载方法:Procedure ExampleThread.Execute;
即可!
 
我从来没有编过多线程程序了,代码能具体具体点了
 
好像都没有同步的。
 
用 Application->ProcessMessages();试一试
//////////////////////////////////////////////////////////////////////Press=new TPress(Application);
Press->Show();//ノ??篈bar
Press->CGPress->AddProgress(1);
Press->CGPress->AddProgress(1);
begin
ConnAndGetSybaseData();
//秨﹍弄计沮
Press->CGPress->AddProgress(100);
Application->ProcessMessages();
Press->Close();
 
TPress是什么东西?
 
将问题简单化:
Type
TOneForm=class(TForm)
.
.
private
FOneClass:TOneClass;
public
.
.
end;
procedure TOneForm.Btn_SaveClick(Sender: TObject);
begin
StatusBar1.Panels[1].Text:='开始保存';
FOneClass.SaveToDB;
StatusBar1.Panels[1].Text:='保存完毕';
end;
怎样用线程来替代这个FOneClass.SaveToDB?
请把Execute写一下,其中,用TQuery来操作表,保存数据和ProgressBar同步
也即ProgressBar.StepIt在Query的ExecSQL之后。
这样不难吧?
 
初学者,指导请详细点
只有人看,没有人说吗?
 
这样行不?请高手指正!怎样才能用线程实现ProgressBar和Query1的同步?不用事件,对事件我自己也能做
TSaveThread=class(TThread)
private
FProgressBar:TProgressBar;
FQuery:TQuery;
FNowExecSQL: Boolean;
procedure BarFwAfterExecSQL;
protected
procedure Execute;override;
public
constructor Create(Suspended:Boolean;ProgressBar:TProgressBar;
Query:TQuery);
property NowExecSQL:Boolean read FNowExecSQL write FNowExecSQL;
end;
{$R *.DFM}
{ TSaveThread }
constructor TSaveThread.Create(Suspended: Boolean;
ProgressBar: TProgressBar;Query:TQuery);
begin
inherited Create(Suspended);
FProgressBar:=ProgressBar;
FQuery:=Query;
end;

procedure TSaveThread.BarFwAfterExecSQL;
begin
//FQuery.ExecSQL;
if FNowExecSQL then
begin
FProgressBar.StepIt;
FNowExecSQL:=False;
end;
end;

procedure TSaveThread.Execute;
begin
while not terminateddo
Synchronize(BarFwAfterExecSQL);
end;
.
.
.
//创建线程
procedure TForm1.FormCreate(Sender: TObject);
begin
FSaveThread:=TSaveThread.Create(False,ProgressBar1,Query1);
end;
//执行调用
procedure TForm1.InsertTeams(TeamsAr:TeamsArray);
var
i:Integer;
SQLText:String;
begin
SQLText:='Insert Into SaveTest Values(:PNo,:PTeam,:PPlays,:PPoints)';
for i:=Low(TeamsAr) to High(TeamsAr)do
begin
with Query1do
begin
Close;
SQL.Clear;
SQL.Text:=SQLText;
ParamByName('PNo').AsString:= TeamsAr[i,1];
ParamByName('PTeam').AsString:= TeamsAr[i,2];
ParamByName('PPlays').AsString:=TeamsAr[i,3];
ParamByName('PPoints').AsString:=TeamsAr[i,4];
ExecSQL;//执行SQL
FSaveThread.NowExecSQL:=True;//调用线程????????
end;
end;
CurRecords;//刷新
end;
 
问题已经自己解决了
 
如何﹖﹖﹖﹖﹖﹖﹖﹖﹖﹖﹖
 
继承TQuery,在exesql时候,加上progressbar前进一步
 
这些显示都简单,但是怎么比较准确的让Progressbar反映出SQL执行的进度呢?例一个Sql执行完共要一分钟(这个时间在执行前怎么得到?),我们可以每隔1秒走一步。我想这是最大的问题,谁可以回答?
 
给你一个DEMO:
unit Unit1;
interface
uses
Windows Messages SysUtils Classes Graphics Controls Forms Dia
logs
StdCtrls ComCtrls;
type
TForm1 = class(TForm)
StatusBar1: TStatusBar;
Button1: TButton;
procedure StatusBar1DrawPanel(StatusBar: TStatusBar;
Panel: TStatusPanel;
const Rect: TRect);
procedure Button1Click(Sender: TObject);
private
progressbar: TProgressBar;
barRect: TRect;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.StatusBar1DrawPanel(StatusBar: TStatusBar;
Panel: TStatusPanel;
const Rect: TRect);
begin
barRect := Rect;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
I StepCount : integer;
begin
progressBar := TProgressBar.Create (Form1);
StepCount := 1000;
with progressbardo
begin
top := barrect.top;
left := barrect.left;
width := barrect.right - barrect.left;
height := barrect.bottom - barrect.top;
visible := true;
try
parent := statusbar1;
min := 0;
max := stepcount;
step := 1;
for i := 1 to stepcountdo
stepit;
finally
free;
end;
end;
end;
end.
--
 
单个查询的执行进度?那不可能实现的,连SQL Server自己都不知道什么时候才能完成查询或者执行完存储过程,它怎么可能返回信息告诉你现在正执行到什么地步?
查询的时候MSSQL和Oracle都不知道最终的结果数据有多少个,而你fetch的数据又有多少个.所以根本不可能知道要执行多久.不过我记得Oracle好像有一套机制是可以由SQL语句和客户机通讯,你找找看?
 
多人接受答案了。
 
后退
顶部