Delphi中實現多線程同步查詢 |
|
jackkcg
站務副站長 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
Delphi中實現多線程同步查詢 -------------------------------------------------------------------------------- 優秀的資料庫應用應當充分考慮資料庫訪問的速度問題。通常可以通過優化資料庫、優化 查詢語句、分頁查詢等途徑收到明顯的效果。即使是這樣,也不可避免地會在查詢時閃現一個帶有 SQL符號的沙漏,即滑鼠變成了查詢等待。最可憐的是用戶,他(她)在此時只能無奈地等待。遇到急性子的,乾脆在此時嘗試 Windows中的其他應用程式,結果致使你的資料庫應用顯示一大片白色的視窗。真是無奈! 本文將以簡單的例子告訴你如何實現線程查詢。還等什?,趕快打開Delphi對照著下面的完整源代碼試試吧。 在查詢時能夠做別的事情或者取消查詢,這只是基本的線程查詢,在你閱讀了Delphi有關線程幫助之後能立刻實現。這裏介紹的是多個線程查詢的同步進行。 在Delphi資料庫應用中,都有一個缺省的資料庫會話 Session。通常情況下,每個資料庫應用中只有這一個會話。無論是查詢函數修改資料,在同一時間內只能進行其中的一件事情, 而且進行這一件事情的時候應用程式不能回應鍵盤、滑鼠以及其他的 Windows消息。這就是在 視窗區域會顯示一片空白的原因所在。當然,只要將查詢或資料操縱構造成線程物件,情況會好一些,至少可以接受視窗消息,也可以隨時終止查詢或資料操縱,而不會在螢幕上顯示出太難看的白色。不過,這只是解決了問題的一部分。假如在進行一個線程查詢的時候,用戶通過 按鈕或功能表又發出了另一個查詢的命令,這可如何是好,難道終止正在執行的資料庫訪問嗎? 解決之道就是:多線程同步查詢。 實現多線程同步查詢的基本思想是,?每一個查詢元件(如TQuery元件)創建一個獨佔的 資料庫會話,然後各自進行資料庫訪問。需要特別注意的是,因?Delphi中的 VCL元件大多都 不是線程安全的,所以應當在線程查詢結束後再將DataSource元件與查詢元件關聯,從而顯示 在DBGrid元件中。 下面的例子只實現了靜態的線程同步查詢,即線程物件是固定的,並隨表單的創建和銷毀 而創建和銷毀。你可以就此進行改進,?每一個資料查詢或資料操縱命令創建一個單獨的線程物件,從而達到多線程同步查詢的目的。 注意:應用程式中的線程不是越多越好,因?線程將嚴重吞噬CPU資源,儘管看上去並不明顯。謹慎創建和銷毀線程將避免你的應用程式導致系統資源崩潰。 下面的例子給出了同時進行的兩個線程查詢。第一次按下按鈕時,線程開始執行;以後每次按下按鈕時,如果線程處於挂起狀態則繼續執行,否則挂起線程;線程執行完畢之後將連接 DataSource,查詢結果將顯示在相應的DBGrid中。 { 這裏的多線程同步查詢演示程式僅包括一個工程文件和一個單元文件 } { 表單中放置的元件有: } { 兩個Session元件 } { 兩個Database元件 } { 兩個Query元件 } { 兩個DataSource元件 } { 兩個DBGrid元件 } { 一個Button元件 } { 除非特別說明,否則上述各元件的屬性都取預設值(見各元件注釋) } { 對於Database元件,就和一般設置一樣,有一個正確的連接即可 } { 對於Query 元件,需要在各自的屬性 SQL中添加一些查詢語句,?了 } { 看得更清除,建議不要在兩個Query 元件中填寫相同的查詢語句。 } unit Unit1; interface uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, DBTables, Grids, DBGrids, StdCtrls; type
TForm1 = class(TForm)
Session1: TSession; { 屬性SessionName填寫?S1 }
Database1: TDatabase; { 屬性SessionName選擇?S1 }
Query1: TQuery;{ 屬性Database選擇?Database1;屬性SessionName選擇?S1 }
DataSource1: TDataSource; { 屬性DataSet設置?空 }
DBGrid1: TDBGrid; { 屬性DataSource選擇?DataSource1 }
Session2: TSession; { 屬性SessionName填寫?S2 }
Database2: TDatabase; { 屬性SessionName選擇?S2 }
Query2: TQuery;{ 屬性Database選擇?Database2;屬性SessionName選擇?S2 }
DataSource2: TDataSource; { 屬性DataSet設置?空 }
DBGrid2: TDBGrid; { 屬性DataSource選擇?DataSource2 }
BtnGoPause: TButton; { 用於執行和挂起線程 }
procedure FormCreate(Sender: TObject); { 創建表單時創建線程物件 }
procedure FormDestroy(Sender: TObject); { 銷毀表單時銷毀線程物件 }
procedure BtnGoPauseClick(Sender: TObject); { 執行線程和挂起線程 }
private
public
end; TThreadQuery = class(TThread) { 聲明線程類 }
private
FQuery: TQuery; { 線程中的查詢元件 }
FDataSource: TDataSource; { 與查詢元件相關的資料感知元件 }
procedure ConnectDataSource;{ 連接資料查詢元件和資料感知元件的方法 }
protected
procedure Execute; override;{ 執行線程的方法 }
public
constructor Create(Query: TQuery;
DataSource: TDataSource); virtual; { 線程構造器 }
end; var
Form1: TForm1;
Q1, { 線程查詢物件1 }
Q2: TThreadQuery; { 線程查詢物件2 } implementation {$R *.DFM} { TThreadQuery類的實現 } { 連接資料查詢元件和資料感知元件}
procedure TThreadQuery.ConnectDataSource;
begin
FDataSource.DataSet := FQuery;{ 該方法在查詢結束後才調用 }
end; procedure TThreadQuery.Execute;{ 執行線程的方法 }
begin
try
FQuery.Open; { 打開查詢 }
Synchronize(ConnectDataSource);{ 線程同步 }
except
ShowMessage('Query Error'); { 線程異常 }
end;
end; { 線程查詢類的構造器 }
constructor TThreadQuery.Create(Query: TQuery; DataSource: TDataSource);
begin
FQuery := Query;
FDataSource := DataSource;
inherited Create(True);
FreeOnTerminate := False;
end; { 創建表單時創建線程查詢物件 }
procedure TForm1.FormCreate(Sender: TObject);
begin
Q1 := TThreadQuery.Create(Query1, DataSource1);
Q2 := TThreadQuery.Create(Query2, DataSource2);
end; { 銷毀表單時銷毀線程查詢物件 }
procedure TForm1.FormDestroy(Sender: TObject);
begin
Q1.Terminate; { 銷毀之前終止線程執行 }
Q1.Destroy;
Q2.Terminate; { 銷毀之前終止線程執行 }
Q2.Destroy;
end; { 開始線程、繼續執行線程、挂起線程 }
procedure TForm1.BtnGoPauseClick(Sender: TObject);
begin
if Q1.Suspended then Q1.Resume else Q1.Suspend;
if Q2.Suspended then Q2.Resume else Q2.Suspend;
end; end.
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |