Einzelnen Beitrag anzeigen

Headbucket

Registriert seit: 12. Dez 2013
Ort: Dresden
172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#17

AW: Prozedur mit Parametern an Thread übergeben

  Alt 2. Apr 2014, 13:51
Vielen Dank schonmal für die Antwort. Ich habe mich eben nochmal rangesetzt und bin ein Stück weiter, denke ich.

Wenn die VCL hängt und das nicht passieren soll, dann gibt es nur zwei Möglichkeiten:
- die Operation in einen Thread auslagern, damit der Hauptthread nicht blockiert wird
- immer mal wieder der VCL Zeit geben etwas zu tun (Application.ProcessMessages)
der VCL Zeit geben ist theoretisch möglich. Leider treten dann bei mir andere Probleme auf:
Ich starte eine Messung und muss diese z.B: nach 5 Sekunden wieder beenden. Die 5 Sekunden überbrücke ich mit einem Sleep. Wenn ich das Sleep durch eine Schleife realisiere und immer "Application.ProcessMessages" ausgebe, werden aus den 5 Sekunden mal ganz schnell 12. Vllt werde ich das nochmal mit einem Timer versuchen.

Das ganze in einem Thread auslagern gefällt mir aber ehrlich gesagt noch besser.
Ich habe die Übergabe der Parameter jetzt erstmal mit einem globalen Record gelöst, da es ein kleine Programm mit wenig Daten ist. Kein Problem also.

Ich habe nun ein ganz neues Problem. Ich starte z.B. zwei Threads:
Delphi-Quellcode:
hMyThread[0] := CreateThread(nil, 0, TFNThreadStartRoutine(@GetSPL), nil, 0, iThreadID);
  hMyThread[1] := CreateThread(nil, 0, TFNThreadStartRoutine(@GetVoltage), nil, 0, iThreadID);
  WaitForMultipleObjects(2, @hMyThread, true, Infinite);
Die erste Funktion (GetSPL) ruft eine Klassen-Funktion einer anderen Unit auf. Diese Funktion soll eine EXE-Datei starten und warten, bis diese beendet ist. Die Funktion sieht dabei so aus (habe ich auch aus dem Forum glaube ich):
Delphi-Quellcode:
function TMeasurement.StartAndWait(const ExecuteFile,ParamString: string): boolean;
var
  SEInfo : TShellExecuteInfo;
  ExitCode : DWORD;
begin
  Result := False;
  if not FileExists(ExecuteFile) then Exit;
  FillChar(SEInfo, SizeOf(SEInfo), 0);
  SEInfo.cbSize := SizeOf(TShellExecuteInfo);
  with SEInfo do
    begin
      fMask := SEE_MASK_NOCLOSEPROCESS;
      Wnd := Application.Handle;
      lpFile := PChar(ExecuteFile);
      lpParameters := PChar(ParamString);
      nShow := SW_SHOWMINIMIZED;
    end;
  if ShellExecuteEx(@SEInfo) then //hier bleibt er nun stehen und es geht nicht weiter
    begin
      repeat
        Application.ProcessMessages;
        Sleep(100);
        GetExitCodeProcess(SEInfo.hProcess, ExitCode);
      until (ExitCode <> STILL_ACTIVE) or Application.Terminated;
      Result := True;
    end;
end;
Leider bleibt er dann beim eigentlichen Aufruf der EXE-Datei stehen. Es muss ja irgendwie mit dem "WaitForMultipleObjects" zusammenhängen. Aber wieso? Muss ich diese Funktion nochmal in einen dritten Thread packen?

Grüße
Headbucket

Edit: Ich habe es jetzt mit einer abgeleiteten Klasse von TThread gelöst. Wenn ich den Funktionsaufruf dort in Execute habe, läuft alles Problemlos durch.

Geändert von Headbucket ( 2. Apr 2014 um 15:05 Uhr)
  Mit Zitat antworten Zitat