想法是這樣的,創建執行緒后,根據需要執行,現場執行完后,不注銷,下次還要繼續啟用執行。
現在的問題是第一次執行后,第二次我不知道怎么呼叫,我創建的時候是create(true),第一次resume正常執行執行緒,onterminate事件也正常執行,但是第二次我不清楚用什么方式執行了,還是執行緒只能一次性的,第二次又需要從新創建?
還有一個問題OnTerminate執行完畢后,執行緒是處于什么狀態,我TForm1.Button2Click(Sender: TObject);時間中呼叫執行緒Terminated是False,按直觀理解,應該是True啊。請大俠幫忙解答下。
{ TMyThread }
constructor TMyThread.Create(ASuspended: Boolean);
begin
inherited Create(ASuspended);
end;
procedure TMyThread.Execute;
begin
inherited;
ShowMessage('3');
end;
{ TForm1 }
procedure TForm1.FormDestroy(Sender: TObject);
begin
if Assigned(FMyThread) then FMyThread.Destroy;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if not Assigned(FMyThread) then
begin
FMyThread := TMyThread.Create(True);
FMyThread.OnTerminate := ThreadTerminate;
FMyThread.Resume
end
else FMyThread.Resume
end;
procedure TForm1.ThreadTerminate(Sender: TObject);
begin
ShowMessage('jieshule');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if FMyThread.Terminated then ShowMessage('Terminated')
else ShowMessage('not Terminated');
end;
uj5u.com熱心網友回復:
procedure TMyThread.Execute;begin
repeat
// do something
Suspend;
until Terminated;
end;
uj5u.com熱心網友回復:
我是用事件+WaitForObject方式實作的,2010還是2007以后,suspend方法已經廢棄了,可以參考下我的實作http://blog.csdn.net/jankercsdn/article/details/8874469
關于執行緒退出處理,還是有不完善的地方,實際使用中有改動,以后整理了再發。
uj5u.com熱心網友回復:
改動的: http://blog.csdn.net/jankercsdn/article/details/51323690uj5u.com熱心網友回復:
比較典型的用法。充分利用Delphi封閉的Tthread一、宣告一個自己的參考Tthread的類
type
TGaugeThread = class(Tthread)
protected
procedure Execute;override;
end;
二、宣告一個執行緒全域變數。一個boolean變數,用于自己控制元件關閉執行緒
var
MyThread:TGaugeThread;
ThreadOn:Boolean;
三、寫一個實作部分
procedure TGaugeThread.Execute;
var i: integer;
begin
ThreadOn:=True;
ThreadEnd:=False;
FreeOnTerminate:=true;
i:=0;
repeat
i:=i+1;
if i>=99 then i:=1;
GaugeFrm.Gauge1.Progress:=i;
application.ProcessMessages;
sleep(75);
until Terminated or ThreadEnd;
GaugeFrm.close;
ThreadOn:=False;
end;
四、呼叫執行緒(可以多次呼叫)
MyThread:=TGaugeThread.Create(False);
五、關閉執行緒
ThreadEnd:=False
uj5u.com熱心網友回復:
在windows上是沒有問題的,因為Suspend實際上是API SuspendThread的包裝,但是在android上可能沒有實作。標注deprecated并非廢棄、不能使用,而是代表不贊同使用、過時的意思(因為跨平臺的緣故)。uj5u.com熱心網友回復:
兄弟們,你們沒有按我的問題回答啊,你們說的說的內容我知道uj5u.com熱心網友回復:
你描述的問題其實是有現成的,“執行緒池”,執行緒需要不停的從List中取出任務進行執行,沒有任務的時候就阻塞在取任務,當然多執行緒要考慮資源競爭的問題,你可以搜索下 “Delphi 執行緒池實作”uj5u.com熱心網友回復:
實際上Delphi對TThread的設計就是把Execute程序用Windows的多執行緒機制運行了一下。所以當Execute程序執行完了,多執行緒也就結束了。
所以說,你想讓執行緒一直活著隨時讓你使用,就不能讓Execute結束。那么你在Execute里就需要寫一個回圈(while/repeat),空閑時Sleep一下防止占用cpu太多,有任務時,設定一下某個變數,Execute里的回圈檢查到這個變數后繼續執行任務(這個任務可以是其他你寫好的函式或者程序)。
uj5u.com熱心網友回復:
執行緒就是執行完,自動結束。否則占用CPU,會造成系統阻塞。uj5u.com熱心網友回復:
同意樓上。或者增加一個定時器,不斷呼叫
uj5u.com熱心網友回復:
procedure TMyThread.Execute;begin
while not terminated do
begin
DoSomeThing;
FEvent.WaitFor(INFINITE);
end;
end;
如果要執行緒再跑一次, 把FEvent帶上信號,FEvent.SetEvent;
uj5u.com熱心網友回復:
使用信號量控制!uj5u.com熱心網友回復:
1. 看情況的,如果執行緒的起停不是很頻繁,那就用的時候創建,不用的時候銷毀。下面是我寫的com口通訊的起停。
procedure TAlmDev.Start;
begin
try
FComPort.Open;
FStop := False;
except on e: exception do
MsgBox(Format('%s: %s', [FComPort.Port, e.message]));
end;
//
if FComPort.Connected and (FComThread = nil) then
begin
FComThread := TCommThread.Create(Self);
end;
end;
procedure TAlmDev.Stop;
begin
FStop := True;
FComPort.Stop;
//
if FComThread <> nil then
begin
FComThread.Free;
FComThread := nil;
end;
//
FComPort.Close;
end;
2。如果是起停非常頻繁,類似于用在執行緒緩沖池的時候,就可以用事件,使執行緒在不用的時候處于阻塞狀態,用到時候發送信號給事件,執行緒就開始回圈了。
3。還有一種用法比較特殊,就是在外部執行緒中,呼叫 suspend 和 resume來起停執行緒,不過這種方法不常用,主要是起停的時候執行緒運行狀態不太好確定。
針對樓主說的已經觸發 ontermitate事件,說明執行緒已經銷毀了,不可能在resume了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/67840.html
標籤:VCL組件開發及應用
