AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Mein TThread blockiert die Anwendung

Ein Thema von Poolspieler · begonnen am 3. Okt 2005 · letzter Beitrag vom 3. Okt 2005
Antwort Antwort
Poolspieler

Registriert seit: 9. Aug 2004
165 Beiträge
 
Delphi 10.3 Rio
 
#1

Mein TThread blockiert die Anwendung

  Alt 3. Okt 2005, 18:16
Hallo,
ich möchte eine von mir geschriebenen Klasse im Hintergrund meiner Applikation laufen lassen.
Ich möchte diese Klasse aber über Buttons "bedienen" können.
Diese Klasse soll dann z.B. einen Labeltext oder andere Dinge verändern.

Hier mein Beispielcode, der eigentlich nur dauern den Labeltext von 1 bis 100 ändern soll:

Delphi-Quellcode:
unit UnitThread;

interface

uses Classes, ExtCtrls, Windows, StdCtrls;

type
  TMeinThread = class(TThread)
  private
    { Private-Deklarationen }
    Text: TLabel;
    procedure machen;
  protected
    procedure Execute; override;
  public
    { Public-Deklarationen }
    constructor Create(_Text: TLabel);
  end;

implementation

uses SysUtils;

constructor TMeinThread.Create(_Text: TLabel);
begin
  inherited Create(false);
  Priority := tpNormal;
  Text := _Text;
end;

procedure TMeinThread.Execute;
begin
  while not Terminated do begin
    Synchronize(machen);
  end;
end;

procedure TMeinThread.machen;
var
  i: integer;
begin
  for i := 1 to 100 do begin
    Text.Caption := IntToStr(i);
  end;
end;

end.
Wenn ich davon in meinem Createereignis des Formulars ein Objekt erzeuge, dann steht die Anwendung - hat jemand einen Tip für mich???

Gruß und danke,
Poolspieler
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Mein TThread blockiert die Anwendung

  Alt 3. Okt 2005, 18:22
das ist klar, denn durch synchronize syncronisierst du den Thread mit der Hauptanwendung. Desweiteren macht es keinen Sinn ein Label aus dem Hauptthread (Hauptanwendung) in einem Thread zu verändern außer du würdest zwischendurch noch ein paar berechnungen im Thread anstellen und das Label nur für den Status verwenden.
Letztendlich ist dein ganzer Thread aber überflüssig weil du die gesammte schleife ja syncronisiert durchführst. Sinn würde es nur machen wenn du die Schleife im Thread laufen lässt und nur das setzen der Labelcaption syncronisierst. Dazwischen im Thread am besten noch paar sleeps damit der thread überhaupt sinn macht.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Poolspieler

Registriert seit: 9. Aug 2004
165 Beiträge
 
Delphi 10.3 Rio
 
#3

Re: Mein TThread blockiert die Anwendung

  Alt 3. Okt 2005, 18:48
Hi,
vielen Dank für Deine Antwort, die hat mich schon ein gutes Stück weiter gebracht.
Mein Beispiel hat jetzt genau das Verhalten, welches ich mir gewünscht habe.

Überarbeitetes Beispiel:
Delphi-Quellcode:
unit UnitThread;

interface

uses Classes, ExtCtrls, Windows, StdCtrls;

type
  TMeinThread = class(TThread)
  private
    { Private-Deklarationen }
    Text: TLabel;
    i: integer;
    procedure machen;
    procedure ausgeben;
  protected
    procedure Execute; override;
  public
    { Public-Deklarationen }
    constructor Create(_Text: TLabel);
  end;

implementation

uses SysUtils;

constructor TMeinThread.Create(_Text: TLabel);
begin
  inherited Create(false);
  Priority := tpNormal;
  Text := _Text;
end;

procedure TMeinThread.Execute;
begin
  while not Terminated do begin
    machen;
  end;
end;

procedure TMeinThread.machen;
begin
  i := 0;
  while i <= 100 do begin
    sleep(500);
    Synchronize(ausgeben);
    Inc(i);
  end;
end;

procedure TMeinThread.ausgeben;
begin
  Text.Caption := IntToStr(i);
end;

end.
Aber ist das wirklich der richtige Weg für so eine Aufgabe?
Ich habe eine sehr große Klasse geschrieben (aktuell noch OHNE Thread), die sehr viele Berechnungen durchführt und äußerst viele Labels, Charts und andere Bedienelemente aktualisieren bzw. auslesen muss. Diese soll nun auf einen Thread umgestellt werden um ein blockieren der Anwendung zu verhindern (application.processmessages funktioniert nicht so ganz, wie ich mir es vorstelle...)

Muss ich nun wirklich für jedes Anzeige- und Bedienelement eine eigene private Variable (hier z.B. das private i:integer) deklarieren? Und dann in einer oder mehreren Methoden die jeweiligen zugehörigen Objekte aktualiseren?
Oder gibt es da eine einfachere Elegantere Lösung?

Gruß,
Poolspieler
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Mein TThread blockiert die Anwendung

  Alt 3. Okt 2005, 18:53
du kannst dir ja auch eine ThreadBasisklasse schreiben welche schon die Funktionen zum aktuallisieren eines Labels etc. mitbringt. Und von dieser klasse kannst du ja dann wieder ableiten.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#5

Re: Mein TThread blockiert die Anwendung

  Alt 3. Okt 2005, 19:50
Zitat von SirThornberry:
das ist klar, denn durch synchronize syncronisierst du den Thread mit der Hauptanwendung.
Schlimmer. Soweit ich weiß, läuft die Synchronize-Methode komplett im Kontext des Hauptthreads.
  Mit Zitat antworten Zitat
Poolspieler

Registriert seit: 9. Aug 2004
165 Beiträge
 
Delphi 10.3 Rio
 
#6

Re: Mein TThread blockiert die Anwendung

  Alt 3. Okt 2005, 20:04
Hi,
vielen Dank für eure Antworten und Anregungen.
Ich werde halt mein ganzes Projekt umschreiben (was aber wohl erstmal nicht mehr als ca. einen Tag in Anspruch nehmen wird - hoffe ich ).

Wen es interessiert:
Ich werde mir ähnlich wie unter Qt (Linux, KDE...) Slots definieren und "Signale" versenden.
Es gibt also slotvariablen (boolean) die privat deklariert sind (z.B. mach_mal_was).
Diese Slotvariablen kann man mit der Methode SetSignal setzen.
In der Execute-Methode frage ich dann zyklisch diese Slotvariablen ab und reagiere dann mit den entsprechenden Funktionen (die dann im Threadkontext verarbeitet werden).
Die "Arbeitsmethoden" greifen nicht mehr direkt auf die Anzeigekomponenten (z.B. mit label.capion) zu, sondern speichern den Inhalt der angezeigt werden soll in einer Zustandsvariablen (für jedes Anzeigeobjekt muss ich dann leider eine Zustandsvariable anlegen... naja...). Es gibt dann Aktualisieren-Methoden, die den Inhalt der Zustandsvariablen an die Anzeigeobjekte weiter geben. NUR diese Aktualisieren-Methoden werden noch mit Synchronisize(aktualisiere) aufgerufen.
Dann muss man nur noch die Stellen im Code finden, an denen es Sinn macht Daten möglichst gebündelt auszugeben...
--> Vielleicht habe ich ja jetzt auch jemandem geholfen, oder eine Anregung gegeben...

Gruß und danke,

Poolspieler
Andreas
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:48 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz