1. 程式人生 > >delphi Parallel 之 TTask 初試

delphi Parallel 之 TTask 初試

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
  System.Generics.Collections;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Memo2: TMemo;
    Memo3: TMemo;
    
procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} uses System.Threading, System.SyncObjs, System.Diagnostics; procedure TForm1.Button1Click(Sender: TObject);
const C = 1000; var TaskArray: array of ITask; I: Integer; ATask: ITask; begin Button1.Enabled := False; Memo1.Clear; Memo2.Clear; Memo3.Clear; SetLength(TaskArray, C); for I := 0 to C - 1 do begin TaskArray[I] := TTask.Create(procedure var Id: string; begin
Id := TThread.Current.ThreadID.ToString; TThread.Queue(nil, procedure begin if Memo1.Lines.IndexOf(Id)=-1 then Memo1.Lines.Add(Id); //Memo2.Lines.Add( IntToStr(Memo2.Lines.Count+1) ); end); end); TaskArray[I].Start; end; TThread.CreateAnonymousThread(procedure var I: Integer; Task: ITask; J: Integer; begin I := C; while I > 0 do begin for Task in TaskArray do if Task.Status = TTaskStatus.Completed then Dec(I); end; TThread.Synchronize(nil, procedure begin Memo1.Lines.Add('OK'); Button1.Enabled := True; end); //否則有記憶體洩漏 for J := 0 to C - 1 do TaskArray[J] := nil; end).Start; if TTask.WaitForAll(TaskArray) then Memo1.Lines.Add('WaitForAll'); end;
procedure TForm1.FormCreate(Sender: TObject); begin ReportMemoryLeaksOnShutdown := True; end; end.

輸出結果

1 WaitForAll
2 7120
3 7064
4 7052
5 OK
6 3272

有時候,輸出結果是:

1 WaitForAll
2 7064
3 7120
4 3272
5 7052
6 OK

測試結果:

1  WaitForAll  不會阻塞主執行緒。

2  100 個 TTask 不會建立100個執行緒,不用寫程式碼就可得到 【執行緒池】 一樣的功能!

3  無法判斷 Task 全部結束??

4  執行緒中涉及到 【介面】時要多注意!

測試環境:

win10 + delphi 10.1 berlin