線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1798
推到 Plurk!
推到 Facebook!

各位大侠,一个有关多线程方面的问题,查阅了大量书籍,可还是没有找到答案。

答題得分者是:jow
treachery
一般會員


發表:5
回覆:3
積分:1
註冊:2007-10-01

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-12-08 22:14:31 IP:222.82.xxx.xxx 訂閱
由于线程里牵扯到VCL控件的调用,因此无法使用CreatThread函数。
因此只能使用Delphi的THhread类实现,实现是实现了,可是现在碰到一个辣手的问题。
创建并激发线程代码放在了一个按钮里,代码如下:

[code delphi]
var
a:LoadServerCommandTread;
begin
a:=LoadServerCommandTread.Create(false);
[/code]

这样可以创建并运行线程是没错,但是,每次启动线程前没有办法知道线程是否在运行,用GetExitCodeThread放在 a:=LoadServerCommandTread.Create(false);获取线程状态,任何时候线程的状态都是已运行。这样一来造成的问
题是,用户如果点N次按钮,那么就有N个同样的线程运行,就造成了一个相当混乱的状况。
找了不少资料,似乎都没有牵扯这个,是因为过于简单,我没有想通,还是怎么的。希望知道的朋友能告诉我,谢谢了。

------
跳舞吧,如同没有任何人注视你一样;
唱歌吧,如同没有任何人聆听一样;
去爱吧,如同从来没有受过伤害一样;
工作吧,如同不需要金钱一样;
活着吧,如同今天是末日一样;
----艾佛烈德.德索萨
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-12-09 02:29:16 IP:123.193.xxx.xxx 訂閱
(1)以下測試程式碼在D7撰寫, TThread在D6與D7下有些差異, 請參考這一篇:

http://delphi.ktop.com.tw/board.php?cid=30&fid=69&tid=90452

(2)要辨識所產生多個執行緒, 你可以在Create執行緒時, 以參數帶入可資判斷的資訊
如 ID.

(3)或以Event方式, 在執行緒運作過程中, 將它的狀態傳出

以下測試碼, 僅供參考...

[code delphi]
unit fMain;

interface

uses
Windows, Classes, SysUtils, Forms, StdCtrls, Controls, ExtCtrls;

type

{ TMyThread }

TLabelUpdatedEvent = procedure(Sender: TObject;
ID: string; Counting: Integer) of object;

TMyThread = class(TThread)
private
FOwner: TForm;
FID: string;
FLabel: TLabel;
FOnLabelUpdated: TLabelUpdatedEvent;
protected
Counting: Integer;
procedure Execute; override;
procedure Update;
public
constructor Create(AOwner: TForm; ID: string);
destructor Destroy; override;
property ID: string read FID;
property OnLabelUpdated: TLabelUpdatedEvent read FOnLabelUpdated write FOnLabelUpdated;
end;

{ TForm1 }

TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
private
List: TStringList;
procedure DO_ON_Terminated(Sender: TObject);
procedure DO_ON_LabelUpdate(Sender: TObject; ID: string; Counting: Integer);
public
end;

var
Form1: TForm1;

implementation
[/code]


[code delphi]
implementation

{$R *.dfm}

{ TMyThread }

constructor TMyThread.Create(AOwner: TForm; ID: string);
begin
inherited Create(True);//Suspend thread execution
FreeOnTerminate := False;
FOwner := AOwner;
FID := ID;
FLabel := TLabel.Create(nil);
FLabel.Left := Random(FOwner.Width-FLabel.Width);
FLabel.Top := Random(FOwner.Height-FLabel.Height);
FLabel.Parent := AOwner;
Resume; //Resume thread execution
end;

destructor TMyThread.Destroy;
begin
FreeAndNil(FLabel);
// inherited;//在D7中, 加call inherited 會產生Exception
end;

procedure TMyThread.Execute;
begin
Counting := 1000;
while not Terminated and (Counting > -1) do
begin
Synchronize(Update);
Application.ProcessMessages;
Sleep(10);
Dec(Counting);
end;
Terminate;
end;

procedure TMyThread.Update;
begin
if Assigned(FLabel) then
begin
FLabel.Caption := IntToStr(Counting);
FLabel.Font.Color := RGB(Random($100),Random($100),Random($100));
FLabel.Update;
if Assigned(FOnLabelUpdated) then
FOnLabelUpdated(Self, FID, Counting);
end;
end;
//------------------------------------------------------------------------------

procedure TForm1.Button1Click(Sender: TObject);
var
ID: string;
Index: Integer;
T: TMyThread;
begin
if Assigned(List) then
begin
ID := IntToStr(Random(MaxInt));
if not List.Find(ID, Index) then
begin
T := TMyThread.Create(Self, ID);
T.OnTerminate := DO_ON_Terminated;
T.OnLabelUpdated := DO_ON_LabelUpdate;
Index := List.AddObject(ID, T);
end;
Caption := Format('New Thread = %d, %s', [Index, ID]);
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
List := TStringList.Create;
List.Sorted := True;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose := Assigned(List) and (List.Count = 0);
if CanClose then FreeAndNil(List);
end;

procedure TForm1.DO_ON_LabelUpdate(Sender: TObject; ID: string; Counting: Integer);
var
S: string;
begin
S := Format('%s, %d', [ID, Counting]);
ListBox1.Items.Add(S);
if ListBox1.Count = 20 then
ListBox1.Items.Delete(0);
ListBox1.Update;
end;

procedure TForm1.DO_ON_Terminated(Sender: TObject);
var
T: TMyThread;
Index: Integer;
begin
if Assigned(Sender) and (Sender is TMyThread)then
begin
T := TMyThread(Sender);
if Assigned(List) and List.Find(T.ID, Index) then
List.Delete(Index);
T.Free;
end;
end;

end.

[/code]
系統時間:2024-05-07 2:57:56
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!