Computerwissenschaften

Multithread-Delphi-Datenbankabfragen mit dbGo (ADO)

Eine Delphi-Anwendung wird standardmäßig in einem Thread ausgeführt. Um einige Teile der Anwendung zu beschleunigen, möchten Sie möglicherweise mehrere Ausführungspfade gleichzeitig in Ihre Delphi-Anwendung einfügen .

 

Multithreading in Datenbankanwendungen

In den meisten Szenarien sind Datenbankanwendungen, die Sie mit Delphi erstellen, Single-Threaded- Anwendungen. Eine Abfrage, die Sie für die Datenbank ausführen, muss abgeschlossen sein (Verarbeitung der Abfrageergebnisse), bevor Sie einen anderen Datensatz abrufen können.

Um die Datenverarbeitung zu beschleunigen, z. B. das Abrufen von Daten aus der Datenbank zum Erstellen von Berichten, können Sie einen zusätzlichen Thread hinzufügen, um das Ergebnis abzurufen und zu bearbeiten (Recordset).

Lesen Sie weiter, um mehr über die 3 Traps in ADO-Datenbankabfragen mit mehreren Threads zu erfahren :

  1. Lösung : “ CoInitialize wurde nicht aufgerufen „.
  2. Lösung: “ Leinwand erlaubt kein Zeichnen „.
  3. Main TADoConnection kann nicht verwendet werden!

 

Kundenbestellungsszenario

In dem bekannten Szenario, in dem ein Kunde Bestellungen mit Artikeln aufgibt, müssen Sie möglicherweise alle Bestellungen für einen bestimmten Kunden zusammen mit der Gesamtzahl der Artikel pro Bestellung anzeigen.

In einer „normalen“ Single-Threaded-Anwendung müssten Sie die Abfrage ausführen, um die Daten abzurufen, und dann über das Recordset iterieren, um die Daten anzuzeigen.

Wenn Sie diesen Vorgang für mehr als einen Kunden ausführen möchten, müssen Sie die Prozedur für jeden der ausgewählten Kunden nacheinander ausführen .

In einem Multithread- Szenario können Sie die Datenbankabfrage für jeden ausgewählten Kunden in einem separaten Thread ausführen und so den Code um ein Vielfaches schneller ausführen lassen.

 

Multithreading in dbGO (ADO)

Angenommen, Sie möchten Bestellungen für 3 ausgewählte Kunden in einem Delphi-Listenfeld-Steuerelement anzeigen.


 Art

 

   TCalcThread=Klasse (TThread)

 

Privat

 

 procedure RefreshCount;

 

geschützt

 

 Prozedur Ausführen; überschreiben ;

 

Öffentlichkeit

 

 ConnStr: breitester Ring;

 

 SQLString: widestring;

 

 ListBox: TListBox;

 

 Priorität: TThreadPriority;

 

 TicksLabel: TLabel;

 


 

 Zecken: Kardinal;

 

   Ende ;

 

Dies ist der Schnittstellenteil einer benutzerdefinierten Thread-Klasse, mit der wir alle Bestellungen für einen ausgewählten Kunden abrufen und bearbeiten.

Jede Bestellung wird als Artikel in einem Listenfeld-Steuerelement ( ListBox- Feld) angezeigt . Das ConnStr- Feld enthält die ADO-Verbindungszeichenfolge. Das TicksLabel enthält einen Verweis auf ein TLabel-Steuerelement, mit dem die Ausführungszeiten von Threads in einer synchronisierten Prozedur angezeigt werden.

Die RunThread- Prozedur erstellt eine Instanz der TCalcThread-Thread-Klasse und führt sie aus.


 Funktion TADOThreadedForm.RunThread (SQLString: widestring; LB: TListBox; Priorität: TThreadPriority; lbl: TLabel): TCalcThread;

 

var

 

   CalcThread: TCalcThread;

 

 Start

 

   CalcThread:=TCalcThread.Create (true);

 

   CalcThread.FreeOnTerminate:=true;

 

   CalcThread.ConnStr:=ADOConnection1.ConnectionString;

 

   CalcThread.SQLString:=SQLString;

 

   CalcThread.ListBox:=LB;

 

   CalcThread.Priority:=Priorität;

 

   CalcThread.TicksLabel:=lbl;

 

   CalcThread.OnTerminate:=ThreadTerminated;

 

   CalcThread.Resume;

 


 

   Ergebnis:=CalcThread;

 

 Ende ;

 

Wenn die 3 Kunden aus dem Dropdown-Feld ausgewählt werden, erstellen wir 3 Instanzen des CalcThread:


 var

 

   s, sg: breitester Ring;

 


 

   c1, c2, c3: ganze Zahl;

 

 Start

 

   s:='SELECT O.SaleDate, MAX (I.ItemNo) AS ItemCount' +

 

'VON Kunde C, Bestellungen O, Artikel I' +

 

'WO C.CustNo=O.CustNo UND I.OrderNo=O.OrderNo';

 


 

   sg:='GROUP BY O.SaleDate';

 


 


 

   c1:=Integer (ComboBox1.Items.Objects [ComboBox1.ItemIndex]);

 

   c2:=Integer (ComboBox2.Items.Objects [ComboBox2.ItemIndex]);

 

   c3:=Integer (ComboBox3.Items.Objects [ComboBox3.ItemIndex]);

 


 


 

   Beschriftung:='';

 


 

   ct1:=RunThread (Format ('% s UND C.CustNo =% d% s', [s, c1, sg]), lbCustomer1, tpTimeCritical, lblCustomer1);

 


 

   ct2:=RunThread (Format ('% s UND C.CustNo =% d% s', [s, c2, sg]), lbCustomer2, tpNormal, lblCustomer2);

 


 

   ct3:=RunThread (Format ('% s UND C.CustNo =% d% s', [s, c3, sg]), lbCustomer3, tpLowest, lblCustomer3);

 

 Ende ;

Fallen und Tricks mit Multithread-ADO-Abfragen

Der Hauptcode befindet sich in der Execute- Methode des Threads :


 Prozedur TCalcThread.Execute;

 

var

 

   Qry: TADOQuery;

 

   k: ganze Zahl;

 

 sein gin

 

geerbt ;

CoInitialize (null);

// CoInitialize wurde nicht aufgerufen

 


 

   Qry:=TADOQuery.Create ( nil );

 

try // MUSS EIGENE VERBINDUNG VERWENDEN // Qry.Connection:=Form1.ADOConnection1;

 

 Qry.ConnectionString:=ConnStr;

 

 Qry.CursorLocation:=clUseServer;

 

 Qry.LockType:=ltReadOnly;

 

 Qry.CursorType:=ctOpenForwardOnly;

 

 Qry.SQL.Text:=SQLString;

 


 

 Qry.Open;

 

 während NICHT Qry.Eof und  NICHT Abgebrochene tun

 

 Start

 

   ListBox.Items.Insert (0, Format ('% s -% d', [Qry.Fields [0] .asString, Qry.Fields [1] .AsInteger]));

 


 

   // Canvas erlaubt KEIN Zeichnen, wenn es nicht über Synchronize aufgerufen wird

 

   Synchronize (RefreshCount);

 


 

   Qry.Next;

 

 Ende ;

 

endlich

 

 Qry.Free;

 

   Ende;

 


 

   CoUninitialize ();

 

 Ende ;

 

Es gibt drei Fallen, die Sie beim Erstellen von Multithread-Delphi ADO-Datenbankanwendungen lösen müssen :

  1. CoInitialize und CoUninitialize müssen manuell aufgerufen werden, bevor eines der dbGo-Objekte verwendet wird. Wenn CoInitialize nicht aufgerufen wird, wird die Ausnahme “ CoInitialize wurde nicht aufgerufenangezeigt . Die CoInitialize-Methode initialisiert die COM-Bibliothek im aktuellen Thread. ADO ist COM.
  2. Sie können das TADOConnection-Objekt aus dem Hauptthread (Anwendung) * nicht * verwenden. Jeder Thread muss eine eigene Datenbankverbindung erstellen.
  3. Sie müssen die Synchronisierungsprozedur verwenden , um mit dem Hauptthread zu „sprechen“ und auf alle Steuerelemente im Hauptformular zuzugreifen.

Similar Posts

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.