![]() |
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:
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):
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;
Code:
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:
public synchronized void SetValue(string AValue) {
FMycxRichEdit.Lines.Text = AValue; }
Delphi-Quellcode:
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.
//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; Ich würde mich freuen, wenn der ein oder andere mir dazu ein paar Tipps geben könnte =) |
AW: Weitere Synchronisierungsmöglichkeiten ?
Zitat:
|
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. |
AW: Weitere Synchronisierungsmöglichkeiten ?
Probiers doch mal mit Messages... PostMessage ...
|
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: |
AW: Weitere Synchronisierungsmöglichkeiten ?
Ist die DLL in Delphi geschrieben?
|
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.
|
AW: Weitere Synchronisierungsmöglichkeiten ?
Mir würden dies bzgl. zwei Möglichkeiten einfallen:
|
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: |
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 ![]() Ein fast ungebremstes Verhalten bekommt man mit ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:05 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