2008-09-16 3 views
12

Ich möchte in der Lage sein, ein TDataSet asynchron in einem eigenen Thread zu öffnen, so dass der Haupt-VCL-Thread bis dahin fortgesetzt werden kann und anschließend der Haupt-VCL-Thread aus diesem TDataSet gelesen wird. Ich habe etwas experimentiert und bin in einige sehr seltsame Situationen geraten, also frage ich mich, ob jemand das schon einmal gemacht hat.In Delphi, ist TDataSet Thread sicher?

Ich habe einige Beispiel-Apps gesehen, wo 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 VCL-Haupt-Thread zu lesen, nachdem der andere Thread die Datenquelle geöffnet hat.

Ich mache Win32-Programmierung in Delphi 7, mit TmySQLQuery von DAC for MySQL als mein TDataSet-Nachkomme.

Antwort

5

Sofern Sie das Dataset nur in einem eigenen Thread verwenden möchten, können Sie wie bei jeder anderen Komponente einfach mit dem Befehl "Synchronisieren" mit dem Hauptthread für jedes VCL/UI-Update kommunizieren.
Oder, besser, können Sie die Kommunikation zwischen den Haupt-Thread und Worker-Threads mit Ihrem eigenen Messaging-System implementieren.

Check Hallvard Lösung hier zum Einfädeln:
http://hallvards.blogspot.com/2008/03/tdm6-knitting-your-own-threads.html

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

nach einer Erklärung auf synchronize und seine Ineffizienz:
http://www.eonclash.com/Tutorials/Multithreading/MartinHarvey1.1/Ch3.html

+4

Threading kann auf viel einfachere Weise durchgeführt werden: http://otl.17slon.com – gabr

+0

Ich bemerkte aus den FAQ für die OmniThreadLibrary (Link in Kommentar oben), dass es nur Delphi 2007 und 2009 unterstützt. Hat jemand es auf verwendet D7? –

3

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

Ich glaube jedoch, dass es sehr von der Komponente abhängt. Zum Beispiel könnten dieselben Asta-Komponenten nicht in einer synchronen Weise von irgendetwas anderem als dem Haupt-VCL-Thread geöffnet werden.

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

3

Eine Sache zu beachten, TDataSet zwischen mehreren Threads zu verwenden ist, können Sie nur den aktuellen Datensatz zu einem bestimmten Zeitpunkt lesen. Also, wenn Sie den Datensatz in einem Thread lesen und dann ruft der andere Thread Next dann Sie sind in Schwierigkeiten.

2

Denken Sie auch daran, dass der Thread höchstwahrscheinlich eine eigene Datenbankverbindung benötigt. Ich glaube, was hier benötigt wird, ist ein Multi-Threading- "Halte" -Objekt, um die Daten aus dem Thread in (nur Schreiben) zu laden, die dann nur vom VCL-Haupt-Thread gelesen werden. Verwenden Sie vor dem Lesen eine Art von Synchronisationsmethode, um sicherzustellen, dass Sie nicht gleichzeitig den Text lesen oder den gleichen Moment in Ihre Datei schreiben oder alles in eine Speicherdatei schreiben und eine Synchronisierungsmethode schreiben, um die Hauptanwendung in der Datei zu informieren Hör auf zu lesen.

Ich habe den letzten Ansatz ein paar Mal genommen, depending auf die Anzahl der erwarteten Datensätze (und die Größe des Datasets) Ich habe dies sogar auf eine physische Festplatte Datei auf dem lokalen System. Es funktioniert ganz gut.

1

Ich habe getan, Multithread-Datenzugriff, und es ist nicht einfach:

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

2) Alles, was mit dieser TDataSet-Instanz getan wird, muss im Kontext des Threads erfolgen, in dem es erstellt wurde. Das ist nicht einfach, wenn Sie z.B. ein db-Raster darüber.

3) Wenn Sie z.B. Haupt-Thread-Spiel mit Ihren Daten, ist die einfache Lösung, es in einen separaten Container irgendeiner Art zu verschieben, z. ein Speicher-Dataset

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

... und die Ausnahmebehandlung ist nicht einfach, entweder ...

Aber: Wenn Sie erfolgreich sind, wird die Anwendung wirklich elegant sein!

0

Die meisten TDatasets sind nicht Thread-sicher. Eine, die ich kenne, ist Thread-Safe ist kbmMemtable. Es hat auch die Fähigkeit, ein Dataset zu klonen, so dass das Problem des Verschiebens des Datensatzzeigers (wie von Jim McKeeth erklärt) auftritt. Sie sind einer der besten Datensätze, die Sie erhalten können (gekauft oder frei).