Tutorial :using LocalAsyncVclCall in Delphi



Question:

Actually i am using the AsyncCalls library to execute an Query asynchronously in this way.

       while AsyncMultiSync([RunQuery], True, 10) = WAIT_TIMEOUT do         begin              FrmProgress.refresh; //Update the ellapsed time in a popup form              Application.ProcessMessages;          end;  

and everything works ok.

Now i want to do the same for load the query in a grid.

so i tried this

         while LocalAsyncVclCall(@InitGrid, 10) = WAIT_TIMEOUT do           begin                FrmProgress.refresh;                Application.ProcessMessages;           end;  

but obviously not compile because the type returned by LocalAsyncVclCall is IAsyncCall and not a Cardinal.

also i tried this, but not works because the initgrid procedure is executed but not asynchronously.

             while not LocalAsyncVclCall(@InitGrid, 10).Finished do               begin                    FrmProgress.refresh;                    //Application.ProcessMessages;               end;  

How i can use LocalAsyncVclCall or another function to execute an VCL code asynchronously .

i want something like this.

             while ExecuteMyVCLProcedure(@InitGrid) = WAIT_TIMEOUT do               begin                    FrmProgress.refresh;                    //Application.ProcessMessages;               end;  

UPDATE The InitGrid procedure goes here, the TcxGrid does not provide any event to show the progress of the data load. because that i want to execute this procedure asynchronously.

procedure InitGrid;     begin    cxGrid1DBTableView1.BeginUpdate;    try               cxGrid1DBTableView1.DataController.DataSource:=DataSource1;//in this point assign the query previously executed to the grid.            cxGrid1DBTableView1.ClearItems;         cxGrid1DBTableView1.DataController.CreateAllItems;           for ColIndex:=0 to cxGrid1DBTableView1.ColumnCount-1 do         cxGrid1DBTableView1.Columns[ColIndex].Options.Editing:=False;      finally      cxGrid1DBTableView1.EndUpdate;    end;    end;  

Thanks in advance.


Solution:1

UPDATE The InitGrid procedure goes here, the TcxGrid does not provide any event to show the progress of the data load. because that i want to execute this procedure asynchronously

You can't populate the cxGrid in a different VCL thread because there is only one VCL Thread, the MainThread. Calling LocalAsyncVclCall from the MainThread does nothing else than executing the given function in the thread that calls LocalAsyncVclCall. So it wouldn't do anything different than calling the InitGrid() function in the same thread where your ProcessMessages() call is. Hence ProcessMessages() would be called after the data was loaded into the cxGird what is not what you want.
All the *VclCall() functions are intended to be executed from a different thread than the MainThread.

Without changing the cxGrid's code to support a "progress event" you are out of luck with your attempt.


Solution:2

Use PostMessage to send a custom windows message to FrmProgress.

e.g

WM_PopulateGrid = WM_USER + 1;    procedure WMPopulateGrid(var msg: TMessage); message WM_PopulateGrid;  begin    //load records into the grid.     //You maybe can use a global variable to pass the records from RunQuery    ....  end;  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »