在Delphi中使用LocalAsyncVclCall

时间:2010-04-01 16:19:59

标签: delphi

实际上我正在使用AsyncCalls库以这种方式异步执行查询。

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

一切正常。

现在我想要在网格中加载查询。

所以我试过这个

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

但显然不能编译,因为LocalAsyncVclCall返回的类型是IAsyncCall而不是Cardinal。

我也尝试了这个,但是没有用,因为initgrid过程是执行但不是异步的。

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

我如何使用LocalAsyncVclCall或其他函数异步执行VCL代码。

我想要这样的东西。

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

更新 InitGrid过程在此处,TcxGrid不提供任何事件来显示数据加载的进度。因为我想异步执行这个过程。

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;

提前致谢。

2 个答案:

答案 0 :(得分:3)

  

更新InitGrid过程进行   在这里,TcxGrid不提供任何   事件显示数据的进度   加载。因为我想要执行   这个过程是异步的

您无法在不同的VCL线程中填充cxGrid,因为只有一个 VCL线程,即MainThread。从MainThread调用LocalAsyncVclCall只会在调用LocalAsyncVclCall的线程中执行给定函数。因此,与在ProcessMessages()调用的同一线程中调用InitGrid()函数不会有任何不同。因此,在将数据加载到cxGird之后将调用ProcessMessages(),这不是你想要的 所有* VclCall()函数都是从与MainThread不同的线程执行的。

如果不更改cxGrid的代码以支持“进度事件”,那么您的尝试就会失败。

答案 1 :(得分:-1)

使用PostMessage向FrmProgress发送自定义Windows消息。

例如

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;