J'ai avancé sur ma version avec un thread.
Cela semble fonctionner correctement.

Cette version est moins efficace que celle avec les TFDBatch, mais je voulais comprendre le fonctionnement en utilisant des threads.

Est-ce que cette utilisation vous semble correcte ?

Main.pas

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
unit fMain;
 
interface
 
uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  Data.Bind.Controls, FMX.Layouts, FMX.ListBox, Fmx.Bind.Navigator,
  FMX.StdCtrls, FMX.Controls.Presentation;
 
type
  TForm3 = class(TForm)
    ProgressBar1: TProgressBar;
    Button1: TButton;
    BindNavigator1: TBindNavigator;
    ListBox1: TListBox;
    OpenDialog1: TOpenDialog;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    procedure LoadList(Sender: TObject; lst: TStrings);
    procedure StepProgress(Sender: TObject; val: Integer);
  public
  end;
 
var
  Form3: TForm3;
 
implementation
 
{$R *.fmx}
 
uses
  uLoadWithThread;
 
{ TForm3 }
 
procedure TForm3.LoadList(Sender: TObject; lst: TStrings);
var
  str: string;
begin
  Label1.Text := 'Loading list';
  ListBox1.Items.BeginUpdate;
  ListBox1.Items.Assign(lst);
  ListBox1.Items.EndUpdate;
  Label1.Text := 'Finished';
end;
 
procedure TForm3.StepProgress(Sender: TObject; val: Integer);
begin
  ProgressBar1.Value := val;
end;
 
procedure TForm3.Button1Click(Sender: TObject);
var
  thread: TLoadWithThread;
begin
  if (not OpenDialog1.Execute) then
    Exit;
 
  ListBox1.Clear;
  ProgressBar1.Value := 0;
  Label1.Text := 'Loading file';
 
  thread := TLoadWithThread.Create;
  thread.Filename := OpenDialog1.FileName;
  thread.OnStep := StepProgress;
  thread.OnEnd := LoadList;
  thread.Resume;
end;
 
end.
uLoadWithThread.pas

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
unit uLoadWithThread;
 
interface
 
uses
  System.Classes;
 
type
  TProcEndEvent = procedure(Sender: TObject; list: TStrings) of object;
  TProcStepEvent = procedure(Sender: TObject; val: Integer) of object;
 
  TLoadWithThread = class(TThread)
  private
    FFilename: string;
    FOnEnd: TProcEndEvent;
    FOnStep: TProcStepEvent;
    FList: TStrings;
    FValue: Integer;
    procedure SetFilename(const Value: string);
    procedure SetOnEnd(const Value: TProcEndEvent);
    procedure SetOnStep(const Value: TProcStepEvent);
  protected
    procedure Execute; override;
  public
    property Filename: string read FFilename write SetFilename;
    property OnStep: TProcStepEvent read FOnStep write SetOnStep;
    property OnEnd: TProcEndEvent read FOnEnd write SetOnEnd;
    property List: TStrings read FList;
    property Value: Integer read FValue;
  end;
 
implementation
 
uses
  IOUtils, System.SysUtils;
 
{ uLoadWithThread }
 
procedure TLoadWithThread.Execute;
var
  arr: TArray<string>;
  i: Integer;
  nb, val: Integer;
begin
{$IFDEF DEBUG}
  NameThreadForDebugging('TLoadWithThread');
{$ENDIF}
 
  if (not TFile.Exists(Filename)) then
    Exit;
 
  FList := TStringList.Create;
  arr := TFile.ReadAllLines(FFilename);
 
  nb := Length(arr);
  FValue := 0;
 
  for i := Low(arr) to High(arr) do
  begin
    FList.Add(arr[i]);
 
    if Assigned(FOnStep) then
    begin
      val := i * 100 div nb;
      if (val <> FValue) then
      begin
        FValue := val;
        Synchronize(nil, procedure
          begin
            FOnStep(Self, Value);
          end);
      end;
    end;
  end;
 
  if Assigned(FOnEnd) then
    Synchronize(nil, procedure
      begin
        FOnEnd(Self, List);
      end);
end;
 
procedure TLoadWithThread.SetFilename(const Value: string);
begin
  FFilename := Value;
end;
 
procedure TLoadWithThread.SetOnEnd(const Value: TProcEndEvent);
begin
  FOnEnd := Value;
end;
 
procedure TLoadWithThread.SetOnStep(const Value: TProcStepEvent);
begin
  FOnStep := Value;
end;
 
end.