Announcement

Collapse
No announcement yet.

Delphi-Flackern

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Delphi-Flackern

    Noch eine Frage zum Thema Threads: Ich erstelle in meinem Programm viele Threads, die nacheinander mit der Thread.Free Methode beendet werden. Wenn ich dann das Programm beende, flackert die Delphi Oberfläche eine ganze Zeit lang. Ungefähr so oft, wie die Anzahl der Threads, die ich erstellt hatte. Beende ich die Threads falsch.. oder vielleicht gar nicht...

  • #2
    Hallo,

    wie sieht ein kurzes, einfaches Beispiel aus, mit dem dieses Verhalten jederzeit reproduziert werden kann

    Comment


    • #3
      unit Unit1;

      interface

      uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

      type
      TForm1 = class(TForm)
      procedure FormCreate(Sender: TObject);
      private
      { Private-Deklarationen }
      public
      { Public-Deklarationen }
      end;

      TTest = class(TThread)
      private
      procedure execute; override;
      public
      end;

      var
      Form1: TForm1;

      implementation

      {$R *.DFM}

      procedure TTest.execute;
      begin
      self.Free;
      self.FreeOnTerminate := True;
      end;

      procedure TForm1.FormCreate(Sender: TObject);
      var
      vTest : TTest;
      i : integer;
      begin
      for i := 1 to 100 do
      vTest := tTest.Create(false);
      application.Terminate;
      end;

      end

      Comment


      • #4
        Hallo,

        warum wird <b>Self.Free</b> aufgerufen? In der Delphi-Hilfe sind zu <b>FreeOnTerminate</b> die folgenden Sätze zu finden: "<i>Mit FreeOnTerminate wird festgelegt, ob das Thread-Objekt nach Beendigung des Threads automatisch freigegeben wird. Setzen Sie FreeOnTerminate auf True, wenn Sie Threads nach deren Ausführung <b>nicht</b> explizit freigeben möchten.</i>".

        Wird die Zeile <b>Self.Free</b> auskommentiert, so ist in Delphi über <b>Ansicht | Debug-Fenster | Threads</b> deutlich zu sehen, dass die Threads nach dem Programmstart bereits wieder entsorgt wurden (da Execute sofort zurückkehrt). In der originalen Fassung (mit Self.Free-Aufruf) bleiben die Threads jedoch als Leichen zurück.

        Das Verhalten kann gut beobachtet werden, wenn ein <b>Sleep</b>-Aufruf hinzugefügt wird:
        <pre>
        procedure TTest.execute;
        begin
        FreeOnTerminate := True;
        Sleep(5000);
        end;
        </pre&gt

        Comment


        • #5
          hier ist eine etwas korrigierte Version, die immernoch flackert...<BR>
          <BR>
          unit Unit1;<BR>
          <BR>
          interface<BR>
          <BR>
          uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, <BR>Dialogs;<BR>
          <BR>
          type TForm1 = class(TForm)<BR>
          procedure FormCreate(Sender: TObject);<BR>
          private { Private-Deklarationen }<BR>
          public { Public-Deklarationen }<BR>
          end;<BR>
          <BR>
          TTest = class(TThread)<BR>
          private<BR>
          public<BR>
          procedure execute; override;<BR>
          end;<BR>
          <BR>
          var Form1: TForm1;<BR>
          <BR>
          implementation<BR>
          <BR>
          {$R *.DFM}<BR>
          <BR>
          procedure TTest.execute;<BR>
          begin<BR>
          self.FreeOnTerminate := True;<BR>
          sleep(5000);<BR>
          end;<BR>
          <BR>
          procedure TForm1.FormCreate(Sender: TObject);<BR>
          var<BR>
          vTest : TTest;<BR>
          i : integer;<BR>
          begin<BR>
          for i := 1 to 100 do<BR>
          begin<BR>
          vTest := tTest.Create(false);<BR>
          vTest.Terminate;<BR>
          end;<BR>
          application.Terminate;<BR>
          end;<BR>
          <BR>
          end.<BR&gt

          Comment


          • #6
            Hallo,

            da nur eine einzige lokale Variable vom Typ TTest deklariert wurde, ist diese nur für den ersten Schleifendurchlauf geeignet. Bereits beim zweiten Schleifendurchlauf entsteht eine "Leiche" (der Zeiger auf die 1. TTest-Instanz wird überschrieben). Besser wäre folgendes:
            <pre>
            procedure TForm1.FormCreate(Sender: TObject);
            var
            i : integer;
            begin
            for i := 1 to 100 do
            with TTest.Create(False) do
            FreeOnTerminate := True;
            end;
            </pre>
            Der Aufruf der TThread-Methode <b>Terminate</b> ist völlig nutzlos, wenn nicht innerhalb von <B>Execute</b> dies auch ausgwertet wird (Beispiel: <i>while (not Terminated) do...</i>). Außerdem muss das Programm über die Kombination von <b>Terminate</b> + <b>WaitFor</b> auf das Ende der Threads warten, bevor es sich selbst beendet

            Comment


            • #7
              Hi

              Nocheins: Was heist viele Thread's ?? Normalerweise bremst JEDER zusätzliche Thread das System aus, egal in welchem Threadmodus. Jeder Thread ist eine "komplizierte" Resource für das System. Einfach mal so viele viele Threads zu erzeugen ist also wenig sinnvoll. Ausschließlich in Mehrprozessoren Systemem stellen die einzelnen Thread eigenen JOB's dar, und können dann einem Prozessor zugeordnet werden. Dadurch wird's dann schneller.

              Ich empfehle Dir mal die Delphihilfe und die mitgelieferten Beispiele über Threads genau zu studieren, es fehlt Dir das Basiswissen, das zeigt Deine grundverkehrte Herangehensweise und Verständniss.
              Das ist keine Kritik, sondern der beste Ratschlag für einen Threadanfänger. Die Hilfe/Beispielprojekte erleichtern ungemein das Verständniss und ersparen so manchen Irrweg.

              Gruß Hage

              Comment

              Working...
              X