AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Das Chrome-Embedded-Framework und die Synchronisierung ohne TThread.Symchronize.
Thema durchsuchen
Ansicht
Themen-Optionen

Das Chrome-Embedded-Framework und die Synchronisierung ohne TThread.Symchronize.

Ein Thema von HintByError · begonnen am 6. Jun 2022 · letzter Beitrag vom 7. Jun 2022
 
HintByError

Registriert seit: 13. Dez 2018
Ort: Marburg
21 Beiträge
 
Delphi XE2 Professional
 
#1

Das Chrome-Embedded-Framework und die Synchronisierung ohne TThread.Symchronize.

  Alt 6. Jun 2022, 21:42
Die Klasse „TChromium“ bietet das Setzen Methodenzeiger für eine Reihe von Ereignissen an. Die auf diesem Weg eingebundenen Methoden werden nicht auf dem Hauptthread ausgeführt, sondern auf einem nebenläufigen Thread. Dabei ist „TChromium“ nicht von „TThread“ abgeleitet und es bietet sich nicht die Synchronisierung auf den Hauptthread mittels „TThread.Synchronize“ an. Lange Rede kurzer Sinn, ich habe eine funktionierende Lösung mittels einer Erweiterung von „TTimer“ durch eine Hilfsklasse. Ich stelle die Lösung hier in Skizzenform zur Diskussion vor. Es kann sein, dass es noch eine einfachere Lösung gibt, deren ich mir nicht bewusst bin. Suchanfragen mittels globaler Suchmaschinen haben aber gezeigt, dass das Problem nicht generell befriedigend behandelt wird.

Synchronisiert werden soll der Methodenzeiger „OnDownLoadUpdated“ einer „TChromium“-Instanz. Wenn die zugeordnete Methode aufgerufen wird, dann ist im Anweisungsblock die Bedingung

  GetCurrentThreadId <> MainThreadId

erfüllt. So kann man programmiert nachfragen, ob eine Routine in einem nebenläufigen Thread ausgeführt wird. Man kann auch in Ansicht->Debug-Fenster->Threads nachsehen. Der erste gelistete Thread ist der Hauptthread und der aktive ist markiert.

Innerhalb von „OnDownLoadUpdated“ lässt sich abfragen, ob der Download abgeschlossen worden ist:
Delphi-Quellcode:
  downloadInProgress := downloadItem.IsInProgress and
    (downloadItem.FullPath <> '');
Die Feldvariable „downloadInProgress“ ist false, wenn der Download abgeschlossen ist. Diese Feldvariable wird auch von „OnCanClose“ des Hauptformulars verwendet.

Wenn der Download abgeschlossen ist, dann soll ein Panel mit einer Schaltfläche zum Anzeigen der Datei über „ShellExecute“ sichtbar gemacht werden und dabei der Dateiname auf der Schaltfläche angezeigt werden. Dies muss auf dem Hauptthread erfolgen. Damit der entsprechende Code auf dem Hauptthread ausgeführt werden kann, wird ein „Timer“-Objekt auf unkonventionelle Weise verwendet. Es ist so, dass die dem Feld „OnTimer“ zugeordnete Methode garantiert auf dem Hauptthread ausgeführt wird. Diese kann dann selbst den Timer über die Eigenschaft „Enabled“ ausschalten, sodass die Methode „OnTimer“ exakt einmal und nicht öfter ausgeführt wird. Ferner ist eine Objektsperre mittels „System.TMonitor.Enter“ notwendig, um entsprechende Felder aus dem Hauptformular, dem die „OnTimer“-Methode zugeordnet ist, für die Parameterübergabe an die „OnTimer“-Methode zu reservieren.

Erweiterung der Klasse „TTimer“ mittels der Hilfsklasse „TThreadTimer“:
Delphi-Quellcode:
  TThreadTimer = class helper for TTimer
    procedure enterNotification;
    procedure runNotification(notification:TNotifyEvent);
    procedure exitNotification;
    class procedure notificationFinished(Sender:TObject);
  end;
Implementation:
Delphi-Quellcode:
  procedure TThreadTimer.enterNotification;
  begin
    System.TMonitor.Enter(self); //Objektsperre.
    repeat until Enabled=false;
//warten auf nicht abgeschlossene „OnTimer“-Methode
  end;

  procedure TThreadTimer.runNotification(notification:TNotifyEvent);
  begin
    OnTimer := notification; //Methodenzeiger setzen
    Enabled := true; //Methodenaufruf per Timer zulassen
  end;

  procedure TThreadTimer.exitNotification;
  begin
    System.TMonitor.Exit(self); //Objektsperre aufheben
  end;

  class procedure TThreadTimer.notificationFinished(Sender:TObject);
  begin
    TTimer(Sender).Enabled := false;
//„OnTimer“ hat Ausführung abgeschlossen und hebt Sperre auf
  end;
Die verwendete „TTimer“-Instanz heißt „tmrResize“. Im Designer ist „Enabled“ auf false gesetzt und das „OnTimer“-Ereignis bleibt dort undefiniert. Es wird dann per Code gesetzt. Der Synchronisierungscode in der nebenläufigen Methode des Ereignisses „OnDownLoadUpdated“:
Delphi-Quellcode:
  if not downloadInProgress and (downloadItem.FullPath <> '') then begin
//Download ist abgeschlossen und eine Zieldatei ist festgelegt
    try
      tmrResize.enterNotification;
//Reservierung der „TTimer“-Instanz „tmrResize“ und des ...
//Zugriffs auf die Feldvariablen für die Parameterübergabe.
      latestDownload := copy(downloadItem.FullPath, 1,
        Length(downloadItem.FullPath));
//Parameter für das „OnTimer“-Ereignis setzen
      tmrResize.runNotification(showPnlDownloadFeature);
//„showPnlDownloadFeature“ als „OnTimer“-Ereignis verwenden.
    finally
      tmrResize.exitNotification;
//Freigabe des TTimerobjektes. Die Freigabe der Sperre mittels
//„Enabled“ in der „TTimer“-Instanz erfolgt dann im „OnTimer“-
//Ereignis
    end;
  end;
Der Code von „showPnlDownloadFeature“, der auf dem Hauptthread ausgeführt wird, sieht dann wie folgt aus:
Delphi-Quellcode:
  try
    pnlDownloadFeature.Visible := true;
//Panel mit Option Dateiladen sichtbar machen
    btnDownloadFeature.Caption := ExtractFileName(latestDownload) + ' laden';
//Dateinamen als Schaltfeldbeschriftung verwenden.
    Application.ProcessMessages;
//Bildschirm aktualsieren
    Chrome.SetFocus(true);
//Fokus auf Browser belassen
  finally
    TTimer.notificationFinished(Sender);
//abschließend wird die „TTimer“-Instanz deaktiviert und mittels
//„Enabled“=false die Freigabe signalisiert. Diese Methode wird
//mit diesen hier beschriebenen Zugriffen exakt einmal aufgerufen.
  end;
Wolfgang Sauer
  Mit Zitat antworten Zitat
 


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 09:48 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-2025 by Thomas Breitkreuz