14 Stimmen

In Delphi, ist TDataSet Thread sicher?

Ich möchte in der Lage sein, ein TDataSet asynchron in seinem eigenen Thread zu öffnen, so dass der Haupt-VCL-Thread fortsetzen kann, bis das getan ist, und dann haben die Haupt-VCL-Thread aus diesem TDataSet danach lesen. Ich habe einige Experimente gemacht und bin in einige sehr seltsame Situationen geraten, so dass ich mich frage, ob jemand dies zuvor getan hat.

Ich habe einige Beispielanwendungen gesehen, in denen ein TDataSet in einem separaten Thread erstellt wird, es geöffnet wird und dann Daten daraus gelesen werden, aber das ist alles in dem separaten Thread getan. Ich frage mich, ob es sicher ist, aus dem TDataSet aus dem Haupt-VCL-Thread zu lesen, nachdem der andere Thread die Datenquelle geöffnet hat.

Ich mache Win32-Programmierung in Delphi 7 und verwende TmySQLQuery von DAC für MySQL als mein TDataSet-Nachkomme.

5voto

Francesca Punkte 21286

Wenn Sie den Datensatz nur in seinem eigenen Thread verwenden wollen, können Sie einfach synchronize verwenden, um mit dem Hauptthread für jede VCL/UI-Aktualisierung zu kommunizieren, wie bei jeder anderen Komponente.
Oder Sie können die Kommunikation zwischen dem Hauptthread und den Worker-Threads mit einem eigenen Nachrichtensystem implementieren.

siehe Hallvards Lösung für das Threading hier:
http://hallvards.blogspot.com/2008/03/tdm6-knitting-your-own-threads.html

oder diese andere:
http://dn.codegear.com/article/22411

für einige Erklärungen zu synchronize und seinen Ineffizienzen:
http://www.eonclash.com/Tutorials/Multithreading/MartinHarvey1.1/Ch3.html

4voto

Cyphus Punkte 849

Ich habe gesehen, dass es mit anderen Implementierungen von TDataSet gemacht wurde, nämlich in der Asta Komponenten. Diese würden den Server kontaktieren, sofort zurückkehren und dann ein Ereignis auslösen, sobald die Daten geladen wurden.

Ich glaube aber, dass es sehr stark auf die Komponente ankommt. Die gleichen Asta-Komponenten können beispielsweise nicht synchron von einem anderen als dem VCL-Hauptthread geöffnet werden.

Kurz gesagt, ich glaube nicht, dass es eine Einschränkung von TDataSet an sich ist, sondern eher etwas, das implementierungsspezifisch ist, und ich habe keinen Zugriff auf die Komponenten, die Sie erwähnt haben.

3voto

Jim McKeeth Punkte 37652

Eine Sache, die bei der Verwendung desselben Namens zu beachten ist TDataSet zwischen mehreren Threads ist, dass Sie nur den aktuellen Datensatz zu einem bestimmten Zeitpunkt lesen können. Wenn Sie also den Datensatz in einem Thread lesen und dann der andere Thread die Weiter dann sind Sie in Schwierigkeiten.

2voto

skamradt Punkte 15128

Denken Sie auch daran, dass der Thread höchstwahrscheinlich eine eigene Datenbankverbindung benötigt. Ich glaube, was hier benötigt wird, ist ein Multi-Thread-"Holding"-Objekt zum Laden der Daten aus dem Thread in (nur schreiben), die dann nur von der Haupt-VCL-Thread gelesen wird. Vor dem Lesen verwenden Sie eine Art von Syncronisation Methode, um sicherzustellen, dass Ihr nicht lesen im gleichen Moment Ihr Schreiben oder Schreiben im gleichen Moment Ihr Lesen, oder laden Sie alles in eine Speicherdatei und schreiben Sie eine Sync-Methode, um die Haupt-App zu sagen, wo in der Datei zu stoppen lesen.

Ich habe den letzten Ansatz ein paar Mal gewählt, abhängig von der Anzahl der erwarteten Datensätze (und der Größe des Datensatzes) habe ich dies sogar in eine physische Plattendatei auf dem lokalen System übernommen. Das funktioniert recht gut.

1voto

Ich habe einen Multithreading-Datenzugriff durchgeführt, und das ist nicht einfach:

1) Sie müssen eine Sitzung pro Thread erstellen.

2) Alles, was mit dieser TDataSet-Instanz geschieht, muss im Kontext des Threads geschehen, in dem sie erstellt wurde. Das ist nicht einfach, wenn man z.B. ein DB-Gitter darauf platzieren möchte.

3) Wenn Sie z.B. den Haupt-Thread mit Ihren Daten spielen lassen wollen, ist die einfachste Lösung, sie in einen separaten Container zu verschieben, z.B. ein Memory Dataset.

4) Sie benötigen eine Art Signalisierungsmechanismus, um den Hauptthread zu benachrichtigen, sobald der Datenabruf abgeschlossen ist.

...und die Behandlung von Ausnahmen ist auch nicht gerade einfach...

Aber: Wenn Sie es geschafft haben, wird die Anwendung wirklich elegant sein!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X