Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Weitere Synchronisierungsmöglichkeiten ? (https://www.delphipraxis.net/160454-weitere-synchronisierungsmoeglichkeiten.html)

geskill 13. Mai 2011 17:53

Delphi-Version: 2010

Weitere Synchronisierungsmöglichkeiten ?
 
Hallo,
in meinem aktuellen Projekt benutze ich Threads die ich nicht synchronisiert habe bzw. mir das richtige Werkzeug dafür fehlt. Normalerweise ruft man in der TThread-Klasse ganz normal die Synchronize-Methode auf. Jetzt lade ich in der Execute-Methode aber eine DLL, welche ein Interface bekommt, was auch auf VCL-Elemente zugreifen kann. Dieses Interface können mehrere DLLs (jeweils in eigenem Thread) bekommen und auch der Benutzer selber kann auf diese VCL-Elemente z.b. ein Eingabefeld zugreifen.

In der DLL steht mir nun aber keine Synchronize-Methode zur Verfügung. Eigentlich will ich das auch nicht (innerhalb der DLL), vielmehr sollen die entsprechenden kritischen Funktionen im Interface synchronisiert werden (also was dahinter liegt).

Hier mal ein Beispiel wie es momentan ist:
Delphi-Quellcode:
  IBasic = interface
    // weitere Funktionen
    function GetValue: WideString;
    procedure SetValue(aValue: WideString);

// ...

function TIRichEdit.GetValue;
begin
  // der nächste Schritt soll nun Synchronisiert ablaufen
  result := FMycxRichEdit.Lines.Text;
end;

procedure TIRichEdit.SetValue(AValue: WideString);
begin
  // hier auch Synchronisieren
  FMycxRichEdit.Lines.Text := AValue;
end;
In Java was ich gerade an der UNI lerne kann man eine komplette Methode einfach so synchronisieren (egal ob man sich nun im Thread befindet oder nicht):
Code:
public synchronized void SetValue(string AValue) {
        FMycxRichEdit.Lines.Text = AValue;
    }
Im Forum habe ich hier immer mal wieder was von den kritischen Abschnitten gelesen, jedoch kam es so mir so vor, als würde das nur funktionieren werden wenn 2 verschiedene Threads (nicht Hauptthread) auf 1 Objekt zugreifen wollen, was aber überhaupt nichts mit der VCL zutun hat:
Delphi-Quellcode:
//Die Variable genau für 1 VCL Objekt
var CriticalSection: TCriticalSection;

// ...

procedure TIRichEdit.SetValue(AValue: WideString);
begin
  CriticalSection.Enter;
  try
    FMycxRichEdit.Lines.Text := AValue;
  finally
    CriticalSection.Leave;
  end;
end;
In dem Tutorial von Michael Puff über Threads bin ich über die Funktion "InterlockedExchangeAdd" gestolpert, dies wäre ja in der Tat das richtige für mich nur das gibt es ja leider nur für Variablen.

Ich würde mich freuen, wenn der ein oder andere mir dazu ein paar Tipps geben könnte =)

s.h.a.r.k 13. Mai 2011 18:37

AW: Weitere Synchronisierungsmöglichkeiten ?
 
Zitat:

In der DLL steht mir nun aber keine Synchronize-Methode zur Verfügung. Eigentlich will ich das auch nicht (innerhalb der DLL), vielmehr sollen die entsprechenden kritischen Funktionen im Interface synchronisiert werden (also was dahinter liegt).
Warum eigentlich nicht? -> TThread.Synchronize() ist doch eine Klassenmethode und hängt somit nicht an einem Objekt.

geskill 13. Mai 2011 19:40

AW: Weitere Synchronisierungsmöglichkeiten ?
 
Weil ich überhaupt keinen Zugriff mehr auf das Thread-Objekt habe. Das gebe ich der DLL ja nicht mit.

Also nochmal kurz eine Übersicht wie das Programm funktioniert:

Auf dem Hauptprogramm sind diverse VCL Komponenten (Eingabefelder, DropDownfelder ...) diese sind alle in Klassen gekapselt. Die Klassen implementieren ein Interface (IBasic). Der Programmbenutzer kann diese Eingabefelder alle bearbeiten.

Es können aber auch mehrere Threads gestartet werden, welche in der Execute-Methode eine DLL Laden und eine Funktion aufrufen. Dabei wird der Funktion in der DLL das Interface mit übergeben, worüber ich in der DLL dann z.b. Werte aus den Eingabefeldern lesen aber auch Werte schreiben kann. D.h. alles was in der DLL geschieht, ist in einem eigenen Thread.

Problematisch wird es, wenn die Funktion in der DLL nun einen Wert von einem Eingabefeld lesen will, der Benutzer dies aber gerade ändert.

FredlFesl 13. Mai 2011 19:43

AW: Weitere Synchronisierungsmöglichkeiten ?
 
Probiers doch mal mit Messages... PostMessage ...

geskill 13. Mai 2011 22:03

AW: Weitere Synchronisierungsmöglichkeiten ?
 
Mit Messages würde es bestimmt gehen, aber dann müsste ich ja ziemlich viel ändern (überall einen Message-Listener). Und dass dann Kreuz und Quer Windows Nachrichten hin und her geschickt werden gefällt mir auch nicht. Zumal auch mehrere Instanzen von einer Komponente existieren können. Wenn man dann an diese eine Nachricht schickt, wird die andere die dann doch auch bekommen?

Es muss doch eine einfache Möglichkeit geben, wie man sich mit dem Hauptthread synchronisieren kann :lol:

s.h.a.r.k 13. Mai 2011 22:08

AW: Weitere Synchronisierungsmöglichkeiten ?
 
Ist die DLL in Delphi geschrieben?

geskill 13. Mai 2011 22:17

AW: Weitere Synchronisierungsmöglichkeiten ?
 
Ja, aber genau das möchte ich auch offen lassen. Deshalb würde ich gerne wie oben im Ausschnitt angedeutet an dieser Stelle Synchronisationspunkte einfügen. Sprich ich müsste am Code der DLL nichts ändern.

s.h.a.r.k 13. Mai 2011 23:22

AW: Weitere Synchronisierungsmöglichkeiten ?
 
Mir würden dies bzgl. zwei Möglichkeiten einfallen:
  • Alle Properties, die via DLL abgefragt werden können sollen, sollten via CriticalSection/TMonitor oder sonst was abgesichert werden. Dann spielt es keine Rolle mehr, welcher Thread darauf zugreift. Dies kann aber seeeehr komplex werden.
  • Eine weitere Idee wäre es, eine Schnittstelle zu schaffen, mit der ein DLL-Thread kommunizieren kann. Diese Schnittstelle synchronisert dann jeden Aufruf mit dem Mainthread. Vorteil hiervon wäre, dass du die Technik "hinter" der Schnittstelle auch noch austauschen könntest, ohne, dass du die DLLs ändern müsstest.
Vielleicht wäre es für alle anderen noch interessant, wie viele Daten denn für die DLLs zur Verfügung stehen müssen. Sind es wirklich beliebig viele Daten, dann ist so eine Schnittstelle evtl. auch sehr komplex...

geskill 14. Mai 2011 00:58

AW: Weitere Synchronisierungsmöglichkeiten ?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mir jetzt gerade mal ein kleines Testprogramm geschrieben, dass permanent mit 2 Threads auf ein Memo schreibt. Zusätzlich habe ich auch noch versucht Werte in das Memo einzugeben (also manuell). Das ganze habe ich jeweils mit einer TCriticalSection, TMonitor und TMultiReadExclusiveWriteSynchronizer probiert und bei allen drei Klassen kam es nie zu irgendwelchen Fehlern - sprich jeder Zugriff wurde anscheinend sauber synchronisiert.

Eigentlich genau das was ich will, nur habe ich nicht gedacht, dass es so funktioniert. Ich dachte jetzt für die richtige VCL-Synchronisation (also mit dem Hauptthread) wäre noch mehr notwendig. :oops:

Sir Rufo 14. Mai 2011 03:24

AW: Weitere Synchronisierungsmöglichkeiten ?
 
Warum sollte mehr notwendig sein?

Allerdings ist eine CriticalSection auch ein sehr harter Eingriff der alle beteiligten Threads ausbremsen kann bis zum Deadlock.
Ähnlich verhält es sich mit Delphi-Referenz durchsuchenSynchronize.

Ein fast ungebremstes Verhalten bekommt man mit Delphi-Referenz durchsuchenQueue, da hier ein Thread etwas in die Warteschlange des Hauptthreads schickt und nicht auf die Fertigstellung wartet.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:34 Uhr.
Seite 1 von 2  1 2      

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