AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi TThread.Synchronize prophylaktisch verwenden
Thema durchsuchen
Ansicht
Themen-Optionen

TThread.Synchronize prophylaktisch verwenden

Ein Thema von bernau · begonnen am 5. Mär 2025 · letzter Beitrag vom 6. Mär 2025
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von bernau
bernau

Registriert seit: 1. Dez 2004
Ort: Köln
1.301 Beiträge
 
Delphi 12 Athens
 
#1

TThread.Synchronize prophylaktisch verwenden

  Alt 5. Mär 2025, 09:23
Ich habe noch nicht so viel mit Threads gemacht, deshalb brauche ich eure Meinung.

Ich habe eine Klasse die verschiedene Methoden hat, die länger dauern "können".

Die Klasse wurde bisher nie innerhalb eines Threads verwendet.
Im DoNotify kann alles mögliche aufgerufen werden. Auch Bildschirmaktualisierungen.

Der Code innerhalb der aufrufenden Methoden (LongTimePart1 etc.) ist threadsicher. Aber durch den Aufruf
von DoNotify kann ich die ganze Methode nicht als threadsicher ansehen. Daher sehe ich die ganze Klasse nicht als threadsicher an.

Nun möchte ich die Procedure LongTimePart1 innerhalb eine Threads aufrufen. Da LongTimePart1 nicht threadsicher ist, müsste ich
diese innerhalb eines Thread.Synchronize aufrufen. Dann würde aber auch "Mach Viel" im Hauptthread laufen.

Nun mein Gedankengang: Kann ich nicht einfach DoNotify threadsicher machen, in dem ich prophylaktisch dort Thread.Synchronize verwende?
Dann wäre die ganze Klasse threadsicher.

Nun kann es aber sein, dass die Procedure LongTimePart1 im Hauptthread aufgerufen wird. Nun weis ich nicht, ob es Probleme gibt, wenn Thread.Synchronize
nicht innerhalb eines Threads aufgerufen wird sondern im Hauptthread.

Wie ist eure Meinung?

Delphi-Quellcode:

// Dieser Code ist ein stark verkürzter Beispielcode

type
  TWorkerTest = class(TObject)
  private
    FOnNotify: TNotifyEvent;
  public
    property OnNotify: TNotifyEvent read FOnNotify write FOnNotify;
    Procedure DoNotify;
  public
    Procedure LongTimePart1;
    Procedure LongTimePart2;
    Procedure LongTimePart3;
  end;

implementation

{ TWorkerTest }

procedure TWorkerTest.DoNotify;
begin
  //******************************************
  // bestehende Version - Nicht threadsicher
  //
  // if assigned(FOnNotify) then
  // FOnNotify(self);
  //******************************************

  // neue Version - hoffentlich threadsicher
  // Die Methoden, welche OnNotify verwenden,
  // "können" aus einem Thread aufgerufen sein. Müsse aber nicht.
  TThread.Synchronize(nil,
    procedure
    begin
      if assigned(FOnNotify) then
        FOnNotify(Self);
    end);
end;

procedure TWorkerTest.LongTimePart1;
begin
  // Mach viel. Threadsicherer Code.
  DoNotify;
end;

procedure TWorkerTest.LongTimePart2;
begin
  // Mach viel. Threadsicherer Code.
  DoNotify;
end;

procedure TWorkerTest.LongTimePart3;
begin
  // Mach viel. Threadsicherer Code.
  DoNotify;
end;
Gerd
Kölner Delphi Usergroup: http://wiki.delphitreff.de

Geändert von TBx ( 7. Mär 2025 um 09:39 Uhr) Grund: Formatierung repariert
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
772 Beiträge
 
#2

AW: TThread.Synchronize prophylaktisch verwenden

  Alt 5. Mär 2025, 09:29
Zumindest in neueren delphis kannst du das beruhigt auch im hauptthread aufrufen, da es gegebenenfalls dann direkt aufgerufen wird.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.597 Beiträge
 
Delphi 12 Athens
 
#3

AW: TThread.Synchronize prophylaktisch verwenden

  Alt 5. Mär 2025, 09:42
Ich habe noch nicht so viel mit Threads gemacht, deshalb brauche ich eure Meinung.
Ist jetzt zwar ein wenig Eigenwerbung, aber vielleicht investierst du mal ein paar Minuten zum Lesen dieses Artikels: Async Tasks in VCL Projects

Falls du mehrere Stunden erübrigen kannst, bietet sich dieses Buch von Dalija Pasnikar an: Delphi Event-based and Asynchronous Programming
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von bernau
bernau

Registriert seit: 1. Dez 2004
Ort: Köln
1.301 Beiträge
 
Delphi 12 Athens
 
#4

AW: TThread.Synchronize prophylaktisch verwenden

  Alt 5. Mär 2025, 10:17

Ist jetzt zwar ein wenig Eigenwerbung, aber vielleicht investierst du mal ein paar Minuten zum Lesen dieses Artikels: Async Tasks in VCL Projects
Ja. Schon gelesen. Sehr interessant, wie alles aus deinem Blog

Hat mir aber nicht direkt die Frage beantwortet, ob ich Thread.Synchronize unbedenklich im Hauptthread aufrufen kann.



Falls du mehrere Stunden erübrigen kannst, bietet sich dieses Buch von Dalija Pasnikar an: Delphi Event-based and Asynchronous Programming
Danke für den Link.
Gerd
Kölner Delphi Usergroup: http://wiki.delphitreff.de
  Mit Zitat antworten Zitat
Benutzerbild von bernau
bernau

Registriert seit: 1. Dez 2004
Ort: Köln
1.301 Beiträge
 
Delphi 12 Athens
 
#5

AW: TThread.Synchronize prophylaktisch verwenden

  Alt 5. Mär 2025, 10:37
Zumindest in neueren delphis kannst du das beruhigt auch im hauptthread aufrufen, da es gegebenenfalls dann direkt aufgerufen wird.
Danke.

Und hier habe ich auch die Bestätigung gefunden

Zitat von docwiki.embarcadero.com:
Hinweis: Der Aufruf von Synchronize aus dem Haupt-Thread ist sicher.
Gerd
Kölner Delphi Usergroup: http://wiki.delphitreff.de
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.306 Beiträge
 
Delphi 12 Athens
 
#6

AW: TThread.Synchronize prophylaktisch verwenden

  Alt 5. Mär 2025, 11:14
Leider hat TThread.Queue auch dieses Verhalten
und anstatt es zu reparieren, damit die Funktion immer das macht, wie sie heißt,
wurde TThread.ForceQueue erfunden, welches sich auch im Hauptthread "richtig" verhält.

Fazit: Einfach immer ForceQueue statt Queue verwenden.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.597 Beiträge
 
Delphi 12 Athens
 
#7

AW: TThread.Synchronize prophylaktisch verwenden

  Alt 5. Mär 2025, 11:24
Leider hat TThread.Queue auch dieses Verhalten
und anstatt es zu reparieren, damit die Funktion immer das macht, wie sie heißt,
wurde TThread.ForceQueue erfunden, welches sich auch im Hauptthread "richtig" verhält.
Die Krux mit dem Reparieren ist halt oft ein inkompatibles Verhalten bei bestehendem Code, der sich auf das falsche verlässt.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
QuickAndDirty

Registriert seit: 13. Jan 2004
Ort: Hamm(Westf)
1.981 Beiträge
 
Delphi 12 Athens
 
#8

AW: TThread.Synchronize prophylaktisch verwenden

  Alt 5. Mär 2025, 12:05
Leider hat TThread.Queue auch dieses Verhalten
und anstatt es zu reparieren, damit die Funktion immer das macht, wie sie heißt,
wurde TThread.ForceQueue erfunden, welches sich auch im Hauptthread "richtig" verhält.

Fazit: Einfach immer ForceQueue statt Queue verwenden.
Ja ForceQueue ist echt super hilfreich! Da man selber nie weiß in welcher reihenfolge Ereigniss von Userinput erfolgen kommt das bei mir in fast jedes klick ereignis...damit das rendern von irgend einem effekt nicht durch meinen Code unterbrochen wird...
Andreas
Monads? Wtf are Monads?
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.039 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#9

AW: TThread.Synchronize prophylaktisch verwenden

  Alt 5. Mär 2025, 12:26
Die Klasse wurde bisher nie innerhalb eines Threads verwendet.
/klugscheissermodus on

Sie wurde schon immer innerhalb eines Threads verwendet, nämlich des mainthreads.

/klugscheissermodus off

Was ich damit sagen will: deine Änderung macht das nun nicht per se threadsicher sondern sorgt nur dafür, dass OnNotify immer im Mainthread ausgeführt wird. Das muss man dann beim Verwenden wissen. Es wird bei dir vermutlich nicht der Fall sein, da du ja laut deiner Aussage noch nie etwas in einem Nebenthread gemacht hast, aber generell ist man nicht dadurch sicher, dass man Code mit TThread.Synchronize in den Mainthread verschiebt. Denn auch dort kann dann Code ausgeführt werden, der mit einem anderen Nebenthread eine race condition erzeugt.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von bernau
bernau

Registriert seit: 1. Dez 2004
Ort: Köln
1.301 Beiträge
 
Delphi 12 Athens
 
#10

AW: TThread.Synchronize prophylaktisch verwenden

  Alt 5. Mär 2025, 12:42
/klugscheissermodus on -> mainthread




Was ich damit sagen will: deine Änderung macht das nun nicht per se threadsicher sondern sorgt nur dafür, dass OnNotify immer im Mainthread ausgeführt wird. Das muss man dann beim Verwenden wissen. Es wird bei dir vermutlich nicht der Fall sein, da du ja laut deiner Aussage noch nie etwas in einem Nebenthread gemacht hast, aber generell ist man nicht dadurch sicher, dass man Code mit TThread.Synchronize in den Mainthread verschiebt. Denn auch dort kann dann Code ausgeführt werden, der mit einem anderen Nebenthread eine race condition erzeugt.
Stimmt. Darüber habe ich noch gar nicht nachgedacht. Gut zu wissen.
Gerd
Kölner Delphi Usergroup: http://wiki.delphitreff.de
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 21:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz