[Code] [Delphi] Multithreading

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von Prrovoss, 29. Juli 2010 .

  1. 29. Juli 2010
    [Delphi] Multithreading

    hi,
    ich suche eigendlich nur die einfachste methode wie ich die prozedur eines buttonklicks in einem eigenen thread ausführen kann.

    ich hab mir dazu schon ein paar tuts angesehen. allerdings haben die mir nur mäßig dabei geholen^^
     
  2. 29. Juli 2010
    AW: [Delphi] Multithreading

    Hierraus sollte sich doch alles regeben: http://www.hsg-kl.de/faecher/inf/material/delphi/threads/index.php
     
  3. 30. Juli 2010
    AW: [Delphi] Multithreading

    Da du dir ja anscheinend schon ein paar Tuts dir reingezogen hast und bei denen wahrschienlich mit einer TThread Klasse gearbeitet wurde erkläre ich dir mal schnell wie du so eine TThread-Ableitklasse erstellen kannst.

    Delphi bietet eine einfache Möglichkeit eine Abgeleitete TThread Klasse zu erstellen und an seine bedürfnisse anzupassen, dazu gehst du in deinem Projekt auf Datei->Neu->Weitere... anschliessend findest du unter dem Register Neu ein Thread-Objekt welches du auswählst.
    Dann wirst du nach dem Namen der abgeleiteten Klasse gefragt, die nennst du dann wie du willst (zb. TScanThread) und klickst auf ok und bekommst eine vorgefertigte Klasse in der schon die procedure Execute vordefiniert ist.
    Diese Execute procedure wird dann entweder beim erstellen des Objekts, je nach dem was für ein Parameter für CreateSuspended übergeben wird, direkt (false) oder erst später durch den procedure Aufruf von Resume parallel ausgeführt, dh. der Code wird in einem eigenen Thread durchgeführt.

    Die wichtigsten Eigenschaften und Befehle für Thread Objekte, deren Bedeutung du der Docu von Delphi entnehmen kannst sind:
    Code:
    property FreeOnTerminate: Boolean;
    property Priority: TThreadPriority; 
    property Suspended: Boolean; 
    property Terminated: Boolean;
    
    procedure Resume;
    procedure Suspend;
    procedure Terminate;
    [B]procedure Synchronize(Method: TThreadMethod);*[/B]
    
    *procedure Synchronize(Method: TThreadMethod);
    Dies ist wohl die wichtigste Prozedur die zur fehlerfreien Kommunikation zwischen Threads beiträgt. Alle Daten (Variablen/Speicher) die zwsichen mehreren Threads verwaltet werden dürfen nur in der durch diese Prozedure Aufgerufenen Prozedur ausgelesen und beschrieben werden!
    Eine Möglichkeit Werte bzw. Daten an eine Funktion zu übergeben die durch Synchronize aufgerufen wird gibt es leider nicht, man hat aber die mäglichkeit die Austauschdaten in einer Objekt-Eigenschaft zwischen zu Speichern.

    Hier noch ein Beispiel:
    Spoiler
    Code:
    unit Unit2;
    
    interface
    
    uses
     Classes, SysUtils;
    
    type
     TScanThread = class(TThread)
     private
     FValue: Integer;
     protected
     procedure Execute; override;
     procedure Update;
     end;
    
    implementation
    
    uses Unit1;
    
    { TScanThread }
    
    procedure TScanThread.Execute;
    var I: Integer;
    begin
     for I:=0 to 2000000 do
     begin
     FValue := I;
     Synchronize(Update); [COLOR="Green"]// Ruft die Prozedur Update des Objekts auf[/COLOR]
     end;
    end;
    
    procedure TScanThread.Update;
    begin
    [COLOR="Green"] // Daten von MainForm werden von zwei Thread verwaltet
     // Diesem und dem Hauptthread[/COLOR]
     MainForm.Caption := IntToStr(FValue);
    end;
    
    end.
    

    Mfg Rushh0ur
     
  4. 30. Juli 2010
    AW: [Delphi] Multithreading

    Das einfachste was mir bekannt ist waehre CreateThread (winapi/unsynchronisiert)

    Code:
    var
     ThreadID: DWORD; 
     ThreadHandle: THandle;
    
    function ThreadName(zahl: Pointer): LongInt; stdcall;
    begin
     //Code
    end;
    
    //Thread starten:
    ThreadHandle := CreateThread(nil, 0, TFNThreadStartRoutine(@ThreadName), nil, 0, ThreadID);
    
     
  5. 2. August 2010
    AW: [Delphi] Multithreading


    ich habs mal so versucht aber irgendwie bin ich noch nich ganz dahinter gestiegen^^
    ich versuche ja immer noch ne art countdown zu erstellen. dafür benutze ich die komponente timer. den timer im thread also in der zweiten unit zu starten klappt und das mit dem synchronize() läuft auch alles. allerdings is das event ontimer ja immernoch in der mainform.
    also wird es nich ausgeführt solange anderer code in der mainform ausgeführt wird.

    is es denn möglich das irgendwie so umzusetzen wie ich das vorhabe mit nem timer oder muss ich da ne einfache schleife mit sleep in der threadunit erstellen?
     
  6. 2. August 2010
    AW: [Delphi] Multithreading

    Das ist zum Beispiel eine möglichkeit, aber normal macht man den Rechenintensiven Code in einen Thread rein und anschliessend ist ja der Mainthread "unbelastet" und dort kann man dann von mir aus einen Timer runter Zählen lassen; aber da solteste du eventuell auch beachten das der Code auf diversen Rechner verschieden schnell verarbeitet wird und du nicht von einer konstanten Zahl ausgehen kannst.

    Ich würde an deiner Stelle den kompletten rechenintensiven Code in einen Thread auslagern (vor erstellen eines weiteren schützen), denn Timer bzw. die Zeitanzeige komplett weglassen und anstatt dessen eine ProgressBar und nen Label zur Fortschrittsanzeige in Prozent nutzen.
    Den Fortschritt kann man im Thread ja anhand der vorhandenen Datensätze und bearbeiten Datensätzen ausrechnen und mit Sync die Daten an die Form mitteilen.
    Wenn du desweiteren eine "professionelle" Zeitangabe machen willst, dann Vergleichst du einfach (Bearbeite Datensätze/Zeit) mit (Noch vorhandene Datensätze/Zeit) und berechnest dann daraus die geschätzte benötigte Restzeit und gibst diese zusätzlich aus.

    Mfg Rushh0ur
     
  7. 2. August 2010
    AW: [Delphi] Multithreading


    k ich werd mir da ma was ausdenken.

    btw
    wie kann cih den thread wieder beenden?
    ich habs mit

    thread.suspend;
    thread.terminate;

    versucht aber da tut sich nix.

    dann hab ich versucht, das was bei temrinate passiert manuell zu schreiben.

    in der thread unit sieht das dann so aus:

    Code:
    .....
    type
     Timer = class(TThread)
     procedure stop;
    ......
    
    var
    gestoppt : boolean;
    
    implementation
    
    ......
    
    procedure timer.stop;
    begin
    gestoppt := true;
    end;
    
    ........
    
    procedure Timer.Execute;
    begin
     SetName;
    
     { Place thread code here }
    
     while not gestoppt do begin
     synchronize(update);
    
     end;
    end;
    
    
    
    
    

    wenn ich in der mainform dann timer.stop aufrufe kommt folgendes:
    [Error] Unit1.pas(503): This form of method call only allowed for class methods

    ich habe procedure stop; auch mal unter public gesetzt aber da ändert sich auch nix.

    ich steh grade ein bisschen auf dem schlauch^^ oop is schon etwas länger her
     
  8. 3. August 2010
    Zuletzt von einem Moderator bearbeitet: 14. April 2017
    AW: [Delphi] Multithreading

    Em erstellst du das Objekt auch Richtig?

    zb. in deinem Fall:
    Code:
    var oTimer: Timer;
    ...
    oTimer := Timer.Create(true);
    
    Anschliessend kannst du den Thread mit oTimer.Suspend und oTimer.Resume stopen und wieder starten.

    Desweiteren signaliesierst du mit oTimer.Terminate das sich der Thread beenden soll, wobai du die Abfrage, ob ein Beenden Status vorliegt, selbst im Thread mit Terminated prüfen musst.

    Hab dir mal ein Beispiel erstellt (Das Programm zählt in einer belibigen Datei wie oft ein bestimmter Bytewert vorkommt): ByteCounter Src/Bin (zum Testen einfach ne etwas größere Datei auswählen ~100MB)

    Und less dir am besten mal hier das Tut durch, dass sollte dir auch Helfen:
    Einleitung - Delphi-Treff

    Mfg Rushh0ur
     
  9. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.