Saturday, August 22, 2020

Multithreaded Delphi Database Queries With dbGo (ADO)

Multithreaded Delphi Database Queries With dbGo (ADO) By structure, a Delphi application runs in a single string. To accelerate a few pieces of the application you should choose to include a few synchronous ways of execution in your Delphi application. Multithreading in Database Applications In many situations, database applications you make with Delphi are single strung an inquiry you run against the database needs to complete the process of (handling of the question 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 bring and work on the outcome (recordset). Keep perusing to find out about the 3 snares in multithreaded ADO database questions: Unravel: 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 all out number of things per each request. In a typical single strung application you would need to run the inquiry to get the information at that point repeat over the recordset to show the information. In the event that you need to run this activity for more than one client, you have to consecutively run the strategy for every one of the chose clients. In a multithreaded situation you can run the database question for each chosen 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 methodology. The RunThread method makes and runs an example 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 occasions of the CalcThread: var  â s, sg: widestring;  â c1, c2, c3 : 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 fundamental code goes in the strings Execute technique: system TCalcThread.Execute;var   Qry : TADOQuery;  â k : whole 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 comprehend 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 technique instates 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 methodology to converse with the fundamental 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.