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

求教THREAD與VCL控制

答題得分者是:pedro
KFC123_60201
一般會員


發表:58
回覆:18
積分:15
註冊:2006-07-25

發送簡訊給我
#1 引用回覆 回覆 發表時間:2015-09-30 07:08:49 IP:139.78.xxx.xxx 訂閱
各位好, 我在研究DELPHI 的多緒控制。我想設計一個程序, 利用BUTTON 來觸發一個緒來運行一些耗時的工作, 然後同一個按鍵的狀態會變成等待再一次按鍵來結束緒的運行.
[code delphi]
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TVCLThread = class;

TForm1 = class(TForm)
Button1: TButton;

procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);

private
myThread :TVCLThread;
started :Boolean;

public
procedure DoCalc;
end;

TVCLThread = class(TThread)
private
myForm :TForm1;
StartFinished :Boolean;
protected
procedure Execute(); override;
public
constructor Create(aFrom :TForm1; CreateSuspended: Boolean);
procedure SetStartFinished(b :Boolean);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);
begin
started := false;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
started := not started;
if (started) then
begin
Self.Button1.Caption := 'stop';
myThread := TVCLThread.Create(Self, True);
myThread.SetStartFinished(False);
myThread.Resume;
end
else begin
Self.Button1.Caption := 'start';
myThread.SetStartFinished(True);
while not myThread.Finished do Application.ProcessMessages;
end;
end;

procedure TForm1.DoCalc;
var
i, j :Integer;
begin
for i := 1 to 100000 do
begin
for j := 1 to 100000 do
begin
// some calculation here
Sleep(2);
Application.ProcessMessages;
end;
end;
end;

////////////////////
constructor TVCLThread.Create(aFrom: TForm1; CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
Self.myForm := aFrom;
end;

procedure TVCLThread.Execute;
begin
inherited;
Repeat
Synchronize(Self.myForm.DoCalc);
Until (Terminated or Self.StartFinished);
end;

procedure TVCLThread.SetStartFinished(b: Boolean);
begin
Self.StartFinished := b;
end;

end.
[/code]

在緒的EXECUTE函式中, 我使用一個BOOLEAN狀態來決定是否停止緒的運行, 程序運行時BUTTON可以改變狀態, 但是結束緒後主程序無法結束關閉, 請問是甚麼原因呢?
pedro
尊榮會員


發表:152
回覆:1177
積分:865
註冊:2002-06-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2015-09-30 12:20:35 IP:61.222.xxx.xxx 未訂閱
Hi KFC123

程式會卡在DoCalc耗時迴圈裡,

底下是修改後的程式片斷,或許有幫助你釐清問題點, 看看是不是你要的?
[code delphi]
procedure TForm1.Button1Click(Sender: TObject);
begin
started := not started;
if (started) then
begin
Self.Button1.Caption := 'stop';
myThread := TVCLThread.Create(Self, True);
myThread.SetStartFinished(False);
myThread.FreeOnTerminate:=True; //<-----
myThread.Resume;
end
else
begin
Self.Button1.Caption := 'start';
myThread.SetStartFinished(True);
while not myThread.Finished do
Application.ProcessMessages;
end;
end;

procedure TVCLThread.Execute;
var
i, j: integer;
begin
// inherited;
// repeat
// Synchronize(@Self.myForm.DoCalc);
// until (Terminated or Self.StartFinished);
for i := 1 to 100000 do
begin
for j := 1 to 100000 do
begin
//<-------
Inc(TotalValue);
if Terminated then exit;
Synchronize(ShowResult);
end;
end;
end;
[/code]

procedure TVCLThread.ShowResult;
begin
myForm.Edit1.Text:=IntToStr(TotalValue);
end;

===================引 用 KFC123_60201 文 章===================



在緒的EXECUTE函式中, 我使用一個BOOLEAN狀態來決定是否停止緒的運行, 程序運行時BUTTON可以改變狀態, 但是結束緒後主程序無法結束關閉, 請問是甚麼原因呢?



編輯記錄
pedro 重新編輯於 2015-09-30 12:22:31, 註解 無‧
pedro 重新編輯於 2015-09-30 12:25:59, 註解 無‧
blue
中階會員


發表:114
回覆:105
積分:58
註冊:2002-04-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2015-10-20 16:21:05 IP:125.227.xxx.xxx 訂閱
Hi,您好:
可能該Thread要釋放掉才能關閉主程序,
謝謝!
系統時間:2017-11-24 21:01:32
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!