für mein Projekt "Cenonterix" verwende ich die Klasse TProcess, um die einzelnen Prozesse in den dafür vorgesehenen Objekten (TURLDownload, TFileConversion) zu handhaben. Da mehrere Prozesse nebeneinander laufen können, verwende ich Timer, die im Rhythmus von 1 Sekunde (nicht sehr Systemlastig) die Prozessüberwachung durchführen.
Meine Frage: gäbe es eine Möglichkeit, anstatt von Timern für die Prozessüberwachung auf Events zurückzugreifen? Habe bisher keine solche gefunden. Vielleicht stellt ja das System solche Events bereit?
Ich versuche es nach Möglichkeit zu vermeiden, über Timer zu arbeiten, da es eine nicht sehr elegante Lösung darstellt (nur, wenn es nicht anders geht).
Codeschnipsel 1:
Code: Alles auswählen
procedure TURLDownload.Start;
var
InformationProcess: TProcess;
[...]
begin
[...]
if (FStatus < 3) then begin
FStatus := 3;
[...]
FProcess := TProcess.Create(nil);
FProcess.Options := [poUsePipes,poNoConsole];
FProcess.CommandLine := CXMainForm.CScliveEdit.Text+' -q --output-file "'+FOutputDir+DirectorySeparator+FOutputFile+'" "'+FURL+'"';
FProcess.Execute;
FListItem.SubItems.Strings[0] := 'clive is downloading ...';
[...]
FListItem.SubItems.Strings[1] := FOutputFile;
FStatus := 4;
end;
end;
Codeschnipsel 2:
Code: Alles auswählen
procedure TCXMainForm.CXDTimerTimer(Sender: TObject);
var
I, A: Integer;
ProcQueue: Integer;
ProcCount: Integer;
CanBeStarted: Array of TURLDownload;
URLDownload: TURLDownload;
begin
SetLength(CanBeStarted,0);
ProcCount := 0;
ProcQueue := 0;
for I := 0 to CDList.Items.Count-1 do begin
URLDownload := TURLDownload(CDList.Items.Item[I].Data);
if (URLDownload.Status = 4) then begin
URLDownload.Process;
Inc(ProcCount);
end else if (URLDownload.Status = 2) then begin
A := Length(CanBeStarted);
SetLength(CanBeStarted,A+1);
CanBeStarted[A] := URLDownload;
Inc(ProcQueue);
end;
end;
I := 0;
while (ProcCount+I < CSParallelDownloadsSpin.Value) and (I < Length(CanBeStarted)) do begin
CanBeStarted[I].Start;
Inc(I);
end;
CXStatus.Panels.Items[1].Text := 'Downloads: '+IntToStr(ProcCount)+'/'+IntToStr(ProcQueue);
if (ProcCount+I <= 0) then
CXDTimer.Enabled := False;
SetLength(CanBeStarted,0);
end;
Code: Alles auswählen
procedure TURLDownload.Process;
begin
if (FStatus = 4) then begin
if (FProcess.Running = False) then begin
if (FProcess.ExitStatus > 1) then begin
Terminate(1);
with FListItem.SubItems do begin
Strings[0] := 'Failed!';
Strings[1] := '';
end;
CXMainForm.CXTrayIcon.BalloonFlags:= bfError;
CXMainForm.CXTrayIcon.BalloonHint := 'Download failed!'+#13#10+'URL: "'+FURL+'"';
CXMainForm.CXTrayIcon.ShowBalloonHint;
if (FOutputFile <> '') then
end else begin
Terminate(5);
FListItem.SubItems.Strings[0] := 'Successful.';
CXMainForm.CXTrayIcon.BalloonFlags:= bfInfo;
CXMainForm.CXTrayIcon.BalloonHint := 'Download successful.'+#13#10+'URL: "'+FURL+'"';
CXMainForm.CXTrayIcon.ShowBalloonHint;
if (FConversionFile <> '') then
CXMainForm.AddConversionToList(FOutputDir+DirectorySeparator+FOutputFile,FConversionFile);
end;
end;
end;
end;
Code: Alles auswählen
procedure TURLDownload.Terminate(AStatus: Byte);
begin
FStatus := AStatus;
{$I-}
if (FProcess <> nil) then begin
if (FProcess.Running = True) then
FProcess.Terminate(0);
FProcess.Free;
FProcess := nil;
end;
if (FStatus <> 5) and (FOutputFile <> '') and (FileExists(FOutputDir+DirectorySeparator+FOutputFile)) then
DeleteFile(FOutputDir+DirectorySeparator+FOutputFile);
{$I+}
end;
Gruß
Jay