使用Thread,無法顯示資料進度表 |
答題得分者是:william
|
cyl
中階會員 發表:163 回覆:171 積分:66 註冊:2002-07-11 發送簡訊給我 |
我的Thread是insert 大量資料,我想在畫面上顯示進度表和執行時間,
但是不僅劃面沒反應,連資料都沒insert,我看了好久,不知程式哪裡有問題,
可否請高手幫我修改一下程式碼?? unit Unit1; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, DBTables,StdCtrls, ComCtrls,Gauges; type
TMainForm = class(TForm)
Button1: TButton;
BatchMove1: TBatchMove;
ADOConnection1: TADOConnection;
ADOStoredProc1: TADOStoredProc;
Label1: TLabel;
Edit1: TEdit;
StatusBar01: TStatusBar;
StatusBar02: TStatusBar;
StatusBar03: TStatusBar;
StatusBar04: TStatusBar;
StatusBar05: TStatusBar;
procedure Button1Click(Sender: TObject);
procedure StatusBar01DrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
const Rect: TRect); private
{ Private declarations }
public
{ Public declarations }
end; var
MainForm: TMainForm; implementation uses Unit2; {$R *.dfm} procedure TMainForm.Button1Click(Sender: TObject);
var
Thread1,thread2 :TMoveData;
Threads: array[0..11] of TMoveData;
Time1:TDateTime;
F:Double;
i:integer;
begin
Time1:=now;
Thread1 := TMoveData.Create(ADOConnection1,'01');
Thread1.free;
end;
Procedure TMainForm.StatusBar01DrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
const Rect: TRect);
var
Gauge:TGauge;
sGName:String;
begin
sGName:='Gauge' Format('%.2d',[StatusBar.Tag]);
Gauge:=FindComponent(sGName) as TGauge;
if Gauge=nil then
begin
Gauge:=TGauge.Create(Self);
Gauge.Name:=sGName;
Gauge.ForeColor:=clBlue;
end;
case Panel.ID of
4: with Gauge do begin // Tables Progress Component
Parent:=StatusBar;
Left:=Rect.Left;
Top:=Rect.Top;
Height:=Rect.Bottom-Rect.Top;
Width:=Rect.Right-Rect.Left;
end;
end;
end;
end. unit Unit2; interface
uses
Classes {$IFDEF MSWINDOWS} , Windows {$ENDIF},
DB, ADODB, DBTables,Gauges,StdCtrls,Forms,SysUtils,ComCtrls;
type
TMoveData = class(TThread)
private
Gauge:TGauge;
ADOStoredProc1: TADOStoredProc;
ADOQuery1: TADOQuery;
Table1:TTable;
StartTime,Time1:TDateTime;
iThread,DesTable :string;
StatusBar:TStatusBar;
protected
procedure Execute; override;
procedure LstRefresh;
public
OkString:string; // 用來宣告動作完成用
FTotal:Integer;
constructor Create(Source:TADOConnection; i_agym:String);
end; implementation uses Unit1;
constructor TMoveData.Create(Source:TADOConnection;i_agym:String);
begin
iThread:=i_agym; CopyFile(Pchar('D:\khmfdown\source\khmfma.DBF'),
PChar('D:\khmfdown\thisweek\khmfma' iThread '.DBF'),False);
CopyFile(Pchar('D:\khmfdown\source\khmfag.DBF'),
PChar('D:\khmfdown\thisweek\khmfag' iThread '.DBF'),False);
CopyFile(Pchar('D:\khmfdown\source\khmfhe.DBF'),
PChar('D:\khmfdown\thisweek\khmfhe' iThread '.DBF'),False);
CopyFile(Pchar('D:\khmfdown\source\khmfri.DBF'),
PChar('D:\khmfdown\thisweek\dbf\khmfri' iThread '.DBF'),False);
CopyFile(Pchar('D:\khmfdown\source\khmfad.DBF'),
PChar('D:\khmfdown\thisweek\dbf\khmfad' iThread '.DBF'),False);
CopyFile(Pchar('D:\khmfdown\source\khmftr.DBF'),
PChar('D:\khmfdown\thisweek\khmftr' iThread '.DBF'),False);
CopyFile(Pchar('D:\khmfdown\source\khmflo.DBF'),
PChar('D:\khmfdown\thisweek\khmflo' iThread '.DBF'),False);
ADOquery1 :=TADOQuery.Create(Application);
ADOquery1.Connection:= Source;
table1:=TTable.Create(Application);
Table1.TableName :='D:\khmfdown\thisweek\khmfma' iThread '.DBF';
ADOquery1.SQL.Clear;
ADOquery1.SQL.Add ('truncate table ag.tb_main' iThread '@dev2 drop storage');
ADOquery1.ExecSQL ;
inherited Create(false);
end;
procedure TMoveData.Execute;
var
i_sqrList :string;
procedure AddRec(i_sqr :String ;i_table :string);
var
i,j:integer; begin
table1.Open ; with ADOquery1 do begin
table1.Append;
for i:=0 to FieldCount-1 do
table1.FieldByName(Fields.Fields[i].FieldName).Value:=Fields.Fields[i].Value;
end;
table1.Post ;
end;
begin
ADOquery1.SQL.Clear;
StatusBar:=MainForm.FindComponent('StatusBar' iThread) as TStatusBar;
Gauge:=MainForm.FindComponent('Gauge' iThread) as TGauge;
Gauge.Progress:=0; i_sqrList:='select * from ag.tb_main' iThread '@dev2';
ADOquery1.SQL.Clear;
ADOquery1.SQL.Add (i_sqrList);
ADOquery1.Open ;
Gauge.MaxValue:= ADOquery1.RecordCount;
FTotal:=Gauge.MaxValue;
Gauge.Progress:=0;
while not ADOquery1.eof do begin
Synchronize(lstRefresh);
AddRec(i_sqrList,DesTable);
ADOquery1.Next ;
end;
ADOquery1.Free;
Table1.Free;
end;
procedure TMoveData.LstRefresh;
var
F:Double;
begin
Gauge.Progress:=Gauge.Progress 1;
StatusBar.Panels.Items[2].Text:=DesTable;
StatusBar.Panels.Items[5].Text:=format('%d / %d ',[Gauge.Progress,FTotal]);
f:=now()-Time1;
f:=f * (24*60.0);
Mainform.label1.caption:=format('所花時間:%.2f分',[f]);
Application.processmessages;
end;
end.
|
cyl
中階會員 發表:163 回覆:171 積分:66 註冊:2002-07-11 發送簡訊給我 |
|
cyl
中階會員 發表:163 回覆:171 積分:66 註冊:2002-07-11 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
引言:我測出是因為我的資料量過大open時一直有問題, 我的資料有30幾萬筆資料,不知是否有辦法??< > 資料量少是可以嗎?小弟可糊塗了< > 首先 ADO 是建基於 COM 上的,據小的經驗,在 thread 中應先 CoInitialize 才能用 COM , Main Thread 不用另外 CoInitialize 是因為所調用的 unit (e.g. COMObj, COMServ, etc.) 已在 unit 的 initialization 作 CoInitialize 了 (CoUnitialize 在 finalization 內)。 再來看看 TMoveData 並沒有共用 ADOConnection , 它只不過用共同的 connection string 在每條 thread create 另一個 connection ,所以 12 條 thread 就會多 create 12 條 connection 。另外小的並沒有將 ADO connection share 給多 thread 的經驗 ,用猜的: class="code"> procedure TMoveData.Execute; begin FStartTime := Now; while xxx do begin { loop do to the work } end; { work done } FEndTime := Now; end; {... main thread ...} for i := 1 to 12 do Thread[i] := TMoveDate.Create(xxx,xxx); repeat Done := True; for i := 1 to 12 do Done := Done and (Thread[i].OKString<>''); until Done; for i := 1 to 12 do Thread[i].Free; |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |