Saturday, August 22, 2020

Multithreaded Delphi Database Queries With dbGo (ADO)

Multithreaded Delphi Database Queries With dbGo (ADO) By plan, a Delphi application runs in a single string. To accelerate a few pieces of the application you should choose to include a few concurrent ways of execution in your Delphi application. Multithreading in Database Applications In many situations, database applications you make with Delphi are single strung a question you run against the database needs to complete the process of (preparing of the inquiry results) before you can bring another arrangement of information. To accelerate information preparing, for instance, bringing information from the database to make reports, you can add an extra string to get and work on the outcome (recordset). Keep perusing to find out about the 3 snares in multithreaded ADO database inquiries: Fathom: CoInitialize was not called.Solve: Canvas doesn't permit drawing.Main TADoConnection can't be utilized! Client Order Scenario In the notable situation where a client places orders containing things, you may need to show all the requests for a specific client along the absolute number of things per each request. In a typical single strung application you would need to run the inquiry to bring the information at that point repeat over the recordset to show the information. On the off chance that you need to run this activity for more than one client, you have to consecutively run the technique for every one of the chose clients. In a multithreaded situation you can run the database inquiry for each chose client in a different string and in this way have the code execute a few times quicker. Multithreading in dbGO (ADO) Lets state you need to show orders for 3 chose clients in a Delphi list box control. type   TCalcThread class(TThread)  private  â â â procedure RefreshCount;  protected  â â â procedure Execute; override;â â public     ConnStr : widestring;     SQLString : widestring;     ListBox : TListBox;     Priority: TThreadPriority;     TicksLabel : TLabel;     Ticks : Cardinal;  â end; This is the interface part of a custom string class we are going to use to get and work on all the requests for a chose client. Each request gets showed as a thing in a rundown box control (ListBox field). The ConnStr field holds the ADO association string. The TicksLabel holds a reference to a TLabel control that will be utilized to show string executing times in a synchronized system. The RunThread strategy makes and runs an occasion of the TCalcThread string class. work TADOThreadedForm.RunThread(SQLString: widestring; LB:TListBox; Priority: TThreadPriority; lbl : TLabel): TCalcThread;var   CalcThread : TCalcThread; start   CalcThread : TCalcThread.Create(true) ;   CalcThread.FreeOnTerminate : valid;   CalcThread.ConnStr : ADOConnection1.ConnectionString;   CalcThread.SQLString : SQLString;   CalcThread.ListBox : LB;   CalcThread.Priority : Priority;   CalcThread.TicksLabel : lbl;   CalcThread.OnTerminate : ThreadTerminated;   CalcThread.Resume;   Result : CalcThread; end; At the point when the 3 clients are chosen starting from the drop box, we make 3 occurrences of the CalcThread: var  â s, sg: widestring;  â c1, c2, c3 : whole number; start  â s : SELECT O.SaleDate, MAX(I.ItemNo) AS ItemCount  â â â â â â FROM Customer C, Orders O, Items I  â â â â â â WHERE C.CustNo O.CustNo AND 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]) ;   Caption : ;  â ct1 : RunThread(Format(%s AND C.CustNo %d %s,[s, c1, sg]), lbCustomer1, tpTimeCritical, lblCustomer1) ;  â ct2 : RunThread(Format(%s AND C.CustNo %d %s,[s, c2, sg]), lbCustomer2, tpNormal,lblCustomer2) ;  â ct3 : RunThread(Format(%s AND C.CustNo %d %s,[s, c3, sg]), lbCustomer3, tpLowest, lblCustomer3) ; end; Traps and Tricks With Multithreaded ADO Queries The principle code goes in the strings Execute technique: system TCalcThread.Execute;var   Qry : TADOQuery;  â k : number; begin  inherited;  CoInitialize(nil) ;/CoInitialize was not called   Qry : TADOQuery.Create(nil) ; â try//MUST USE OWN CONNECTION/Qry.Connection : Form1.ADOConnection1;     Qry.ConnectionString : ConnStr;     Qry.CursorLocation : clUseServer;     Qry.LockType : ltReadOnly;     Qry.CursorType : ctOpenForwardOnly;     Qry.SQL.Text : SQLString;     Qry.Open;  â â â while NOT Qry.Eof and NOT Terminated do  â â â begin       ListBox.Items.Insert(0, Format(%s - %d, [Qry.Fields[0].asString,Qry.Fields[1].AsInteger])) ;  â â â â â //Canvas Does NOT Allow Drawing if not called through Synchronize       Synchronize(RefreshCount) ;       Qry.Next;  â â â end;â â finally     Qry.Free;  â end;   CoUninitialize() ; end; There are 3 snares you have to realize how to fathom while making multithreaded Delphi ADO database applications: CoInitialize and CoUninitialize must be called physically before utilizing any of the dbGo objects. Neglecting to call CoInitialize will bring about the CoInitialize was not called special case. The CoInitialize strategy introduces the COM library on the present string. ADO is COM.You *cannot* utilize the TADOConnection object from the principle string (application). Each string needs to make its own database connection.You must utilize the Synchronize technique to converse with the principle string and access any controls on the primary structure.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.