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
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 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.
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.
Partager