请问:关于等待对话框和线程,内详

请教:关于等待对话框和线程,内详
点击“查询”时,创建出一个查询线程,进行向服务器查询数据的耗时处理。同时,在主线程内创建一个带有animate的等待对话框,showmodal。由于查询线程中,返回的数据要填充到主线程DBGrid1所绑定的数据集里,所以查询线程的Excute里调用了主线程的成员函数进行查询,查询结束后,将等待对话框的ModalResult置为IDOK。
现在是,如果查询线程里不用Synchronize进行同步,那么等待对话框里能够正常显示(包括animate能正常播放),但大概再查询几次,就会出现“canvas does not allow drawing”的错误。如果不用Synchronize进行同步,那么等待对话框就是一片空白。

焦头烂额中,表述不清楚,还是看大概的代码吧。
【查询按钮的点击事件】:
procedure TForm1.btnQryClick(Sender: TObject);
var
  wait_form: TMyWaitWnd;  
begin
  ...
  F_aParamValue := ...; // 查询条件赋值
  wait_form := TMyWaitWnd.Create(nil);  
  wait_form.Fanimate.Active := True;
  try
  ThreadWaitWnd.Create(wait_form, Self.LoadData);
  wait_form.ShowModal;
  finally
  wait_form.Fanimate.Active := False;
  wait_form.Close;
  wait_form.Free;
  end;
  ...
end;

【被查询子线程调用的函数】:
procedure TForm1.LoadData();
begin
  GetBaInfoList(F_aParamValue, cds1); // 从服务器查询数据,填充到DBGrid1绑定的数据集cds1里。
end;

【查询子线程】:
unit WaitWndThread;

interface
uses
  Classes, windows, WaitWnd, ActiveX;

type
  ThreadWaitWnd = class(TThread)
  private
  { Private declarations }
  myProc: TThreadMethod;
  MyWaitWnd : TMyWaitWnd;
  public
  { Public declarations }
  protected
  procedure Execute; override;
  published
  constructor Create(wait_form: TMyWaitWnd; call_back: TThreadMethod);
  end;

implementation

constructor ThreadWaitWnd.Create(wait_form: TMyWaitWnd; call_back: TThreadMethod);
begin
  inherited Create(False);
  MyWaitWnd := wait_form;
  myProc := call_back;
end;

procedure ThreadWaitWnd.Execute;
var
  msg: TMsg;
begin
  inherited;
  CoInitialize(nil);
  try
  Synchronize(myProc);
  finally
  MyWaitWnd.ModalResult := IDOK;  
  end;
  CoUninitialize;
end;

end.



------解决方案--------------------
用Synchronize相当于在主线程里执行查询,会阻塞主线程的消息循环,因此你的画面会冻结住。这样起一个线程有调用Synchronize的行为说白了就是脱了裤子放屁。

如果不用Synchronize,那你直接在非主线程的线程里执行查询,这样的话,就要注意线程同步,主线程和你的查询线程访问共同资源的同步问题,由于VCL的界面不是多线程安全的,所以你如果没有主动处理多线程同步的话,就会出现那个“canvas does not allow drawing”