AGB  ·  Datenschutz  ·  Impressum  







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

Event in Thread

Ein Thema von Hobbycoder · begonnen am 11. Mär 2017 · letzter Beitrag vom 11. Mär 2017
Antwort Antwort
Hobbycoder

Registriert seit: 22. Feb 2017
961 Beiträge
 
#1

Event in Thread

  Alt 11. Mär 2017, 15:40
Hi,

ich stelle mir grad folgende Frage: Ich könnte ja in einem Thread auch ein Event hinzufügen. Als Beispiel so
Delphi-Quellcode:
type
  TOnSendAnMain=procedure(Sender: TObject; Irgendwas: string) of object;

  TMyThread=class(TThread)
  private
    FOnSendAnMain: TOnSendAnMain;
    procedure DoSendAnMain(Irgendwas: string);
  published
    property OnSendAnMain: TOnSendAnMain read FOnSendAnMain write FOnSendAnMain;
  public
    ...
  end;
wie müsste die procedure DoSendAnMain aussehen?

So
Delphi-Quellcode:
procedure TMyThead.DoSendAnMain(Irgendwas: string);
begin
  if Assigned(FOnSendAnMain) then
    FOnSendAnMain(self, Irgendwas);
end;
oder so:
Delphi-Quellcode:
procedure TMyThead.DoSendAnMain(Irgendwas: string);
begin
  if Assigned(FOnSendAnMain) then
    Synchronize(FOnSendAnMain(self, Irgendwas));
end;
Da sich hinter FOnSendAnMain ja eine Procedure aus einem anderen Thread verbirgt (z.B. Hauptthread) müsste der Zugriff ja Synchron erfolgern, oder sehe ich das falsch, oder ist das hier nicht notwendig?

Gruß Hobbycoder
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Event in Thread

  Alt 11. Mär 2017, 16:14
Über Synchronize ist das korrekt. Sofern die Methode nicht im Mainthread definiert ist müsste man statt Synchronize z.B. CriticalSections verwenden.

Die Methode solltest Du wenn möglich über den Constructor übergeben.
Andernfalls íst es denkbar, dass es bei einer späteren Zuweisung zu Konflikten kommen kann, wenn eine alte Methode gerade ausgeführt wird während eine neue zugewiesen wird. Dann müsste man die Zugriffe nochmal z.B. über eine CriticalSection absichern.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
961 Beiträge
 
#3

AW: Event in Thread

  Alt 11. Mär 2017, 16:21
Ich mache das bisher so, dass ich den Thread Suspended starte, dann die Methoden zuweise und mit Resume dann losmarschieren lasse.

Wie würde denn so ein Create und dann die Zuweisung aussehen? Es wird ja nur ein Pointer übergeben.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Event in Thread

  Alt 11. Mär 2017, 16:56
Delphi-Quellcode:
  TMyThread=class(TThread)
   private
     fOnSendAnMain: TOnSendAnMain;
     procedure DoSendAnMain(Irgendwas: string);
   public
     constructor Create(aOnSendAnMain: TOnSendAnMain); overload;
   end;

constructor TMyThread.Create(aOnSendAnMain: TOnSendAnMain);
begin
  fOnSendAnMain := aOnSendAnMain;
  Create(False);
end;
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
961 Beiträge
 
#5

AW: Event in Thread

  Alt 11. Mär 2017, 16:58
Ja, klar logisch.

Manchmal denke ich etwas zu kompliziert
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#6

AW: Event in Thread

  Alt 11. Mär 2017, 16:58
Das ist doch Jacke wie Hose.

Will sagen: Du kannst beides problemlos machen. Die Variante mit Synchronize hält den Thread halt mehr auf.

Dafür solltest bei dieser Variante:
Delphi-Quellcode:
procedure TMyThead.DoSendAnMain(Irgendwas: string);
begin
  if Assigned(FOnSendAnMain) then
    FOnSendAnMain(self, Irgendwas);
end;
Dokumentieren, dass das Event in einem separaten Thread aufgerufen wird und eventuelle Interaktionen mit der GUI besonders behandelt werden müssen.
Je nachdem wie du das Event auslöst, muss ggf. der Empfängercode anders geschrieben werden. Du hast also die Wahl zwischen Idiotensicher (Synchronize im Thread) oder Performance.

Falls das Event ausschließlich für GUI Darstellung genutzt wird, ist es komplett egal, da ist Variante 2 (Synchronize im Thread) vll. intuitiver.
  Mit Zitat antworten Zitat
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
972 Beiträge
 
Delphi 6 Professional
 
#7

AW: Event in Thread

  Alt 11. Mär 2017, 17:43
Hmm..


Ich würde das wie schon geschrieben über den Contructor lösen:

Delphi-Quellcode:
type
  TOnSendAnMain=procedure(Sender: TObject; Irgendwas: string) of object;

  TMyThread=class(TThread)
  private
    FNeedSync : boolean;
    FIrgendwas: string;
    FOnSendAnMain: TOnSendAnMain;
    procedure DoSendAnMain(Irgendwas: string);
    procedure DoSendAnMainSyc;
  protected
    procedure Execute; override;
    property OnSendAnMain: TOnSendAnMain read FOnSendAnMain write FOnSendAnMain;
    property NeedSync : boolean read FNeedSync write FNeedSync;
  public
    constructor create(AOnSendAnMain: TOnSendAnMain;ANeedSync : boolean);reintroduce;
  end;

implementation

{ TMyThread }

constructor TMyThread.create(AOnSendAnMain: TOnSendAnMain;
  ANeedSync: boolean);
begin
  FIrgendwas := '';
  FOnSendAnMain:= AOnSendAnMain;
  FNeedSync := ANeedSync;
  inherited create(false);
end;

procedure TMyThread.DoSendAnMain(Irgendwas: string);
begin
  FIrgendwas := Irgendwas;
  if FNeedSync then begin
    Synchronize(DoSendAnMainSyc);
  end else
    DoSendAnMainSyc;
end;

procedure TMyThread.DoSendAnMainSyc;
begin
  if Assigned(FOnSendAnMain) then FOnSendAnMain(self, FIrgendwas);
end;

procedure TMyThread.Execute;
begin
  DoSendAnMain('Bla bla bla');
end;

Dadurch kann beim erstellen des Thread-Objectes entschieden werden, ob ein Sync notwendig ist, oder nicht...
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#8

AW: Event in Thread

  Alt 11. Mär 2017, 20:19
Meiner Erfahrung nach ist es in 99% der Fälle unerwünscht, dass der Thread ein komplettes Event intern schon synchronisiert.

Wenn du das Event einfach nur ganz normal auslöst und dokumentierst, dass es im Kontext eines seperaten Threads aufgerufen wird, hat der Benutzer sehr viel mehr Möglichkeiten für spezifische Optimierungen. Wenn z.b. ClientSocket in einem Thread auf eingehende Daten wartet und dann ein Event zur Verarbeitung auslöst, ist in den meisten Fällen ja gar keine Synchronisierung mit dem Main-Thread erforderlich bzw. nur für ein kurzes GUI Update nach der eigentlichen Verarbeitung.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Event in Thread

  Alt 11. Mär 2017, 20:54
Alternativ diese Synchronisierung per Option (Property) aktivierbar/deaktivierbar.
$2B or not $2B
  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 03:39 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