Ich habe alles Unwichtige rausgenommen und ein bisschen Pseudo-Kommentiert, damit man es HALBWEGS nachvollziehen kann
Threads sind nicht das Problem. Denn als ich das alles ohne ObjectList hatte, lief es einwandfrei.
Delphi-Quellcode:
// aProcessFileList_ObjectList enthält "10" Instanzen von TFileEntry
// aProcessFileList_ObjectList.OwnsObjects ist "False"
// aGlobalVars.iMaxCopyThreadCount ist "2"
// iFilesPerThread ist "5"
// Der ganze StringList-Kram ist nur zum TEST da
{*
Dateien z.B.:
- Datei0.txt
- Datei1.txt
- Datei2.txt
- Datei3.txt
- Datei4.txt
- Datei5.txt
- Datei6.txt
- Datei7.txt
- Datei8.txt
- Datei9.txt
*}
aTmpFileList_ObjectList := TObjectList.Create;
aTmpFileList_ObjectList.OwnsObjects := False;
try
for i := 0 to aGlobalVars.iMaxCopyThreadCount - 1 do
begin
Application.ProcessMessages;
try
if aProcessFileList_ObjectList.Count >= iFilesPerThread then
begin
// Liste wird geleert, damit nicht die alten Daten drin sind / SEIN SOLLTEN
aTmpFileList_ObjectList.Clear;
iCnt := iFilesPerThread;
if aProcessFileList_ObjectList.Count - iCnt = 1 then
Inc(iCnt);
{*
Erster Durchgang: aTmpFileList_ObjectList bekommt "Datei0" bis "Datei4"
Zweiter Durchgang: aTmpFileList_ObjectList bekommt "Datei5" bis "Datei9"
*}
for j := 0 to iCnt - 1 do
aTmpFileList_ObjectList.Insert(j, aProcessFileList_ObjectList.Items[j]);
sl := TStringList.Create;
try
{*
Erster Durchgang: aus aProcessFileList_ObjectList wird "Datei4" bis "Datei0" gelöscht
Zweiter Durchgang: aus aProcessFileList_ObjectList wird "Datei9" bis "Datei5" gelöscht
*}
for j := iCnt - 1 downto 0 do
begin
aProcessFileList_ObjectList.Delete(j);
sl.Add(TFileEntry(aTmpFileList_ObjectList.Items[j]).sSourceDirItem);
end;
// StringList-TEST - was ist in der Liste? In eine Datei abspeichern!
sl.SaveToFile(ExtractFilePath(ParamStr(0)) + '__DELETE' + IntToStr(i) + '.txt');
finally
sl.Free;
end;
sl := TStringList.Create;
try
for j := 0 to aTmpFileList_ObjectList.Count - 1 do
begin
sl.Add(TFileEntry(aTmpFileList_ObjectList.Items[j]).sSourceDirItem);
end;
// StringList-TEST - was ist in der Liste? In eine Datei abspeichern!
sl.SaveToFile(ExtractFilePath(ParamStr(0)) + '__' + IntToStr(i) + '.txt');
finally
sl.Free;
end;
if aTmpFileList_ObjectList.Count > 0 then
begin
{*
Erster Durchgang: Thread1 arbeitet "Datei0" bis "Datei4" ab
Zweiter Durchgang: Thread2 arbeitet "Datei5" bis "Datei9" ab
*}
createCopyThread(aTmpFileList_ObjectList);
end;
end
else
break;
except
// ...
end;
end;
// Wenn noch RESTE in der originalen ObjectList sind, dann erstelle damit einen seperaten Thread
// Das ist z.B. der Fall, wenn 11 Dateien verarbeitet werden müssten. Die letzte (elfte) Datei würde hier in einen Thread gepackt werden
if aProcessFileList_ObjectList.Count > 0 then
begin
createCopyThread(aProcessFileList_ObjectList);
end;
end;
finally
aTmpFileList_ObjectList.Free;
end;
////////////////////////////////////////////////////////////////////////////////
procedure createCopyThread(FaFileList: TObjectList);
var
aCopyThread: TCopyThread;
begin
aCopyThread := TCopyThread.Create;
aCopyThread.aFileList := FaFileList;
end;
////////////////////////////////////////////////////////////////////////////////
type
TCopyThread = class(TThread)
private
{ Private-Deklarationen }
FaFileList: TObjectList;
protected
procedure Execute; override;
public
{ Public-Deklarationen }
constructor Create;
procedure Finish(Sender: TObject);
property aFileList: TObjectList read FaFileList write FaFileList;
end;