是否有任何解决方案,以免在等待数据来自数据库时冻结我的用户界面?
示例:
我们有一个adoquery,我们做
adoquery.active:=false; adoquery.active:=true;
当adoquery尝试从db获取数据时,UI中的所有内容都被冻结,如果用户单击,则整个程序变为 没有回应!!
有没有解决这个问题的方法?
答案 0 :(得分:5)
您可以在[eoAsyncExecute,eoAsyncFetch]
中使用ExecuteOptions
,这将要求数据集使用明确的TAdoConnection。
为避免意外行为,您必须在打开数据集之前使用DisableControls
,并在EnableControls
之后使用FetchComplete
。
EnableControls
中的直接调用FetchComplete
可能会导致异常,因此必须使用Postmessage和用户定义的消息。
Const
// define a message for handling completed AsyncFetch after leaving FetchComplete
WM_MYConnect=WM_User + 77;
type
TMyForm = class(TForm)
MyDataSet: TADODataSet;
MyDatasource: TDataSource;
DBGrid1: TDBGrid;
Button1: TButton;
ADOConnection1: TADOConnection;
procedure Button1Click(Sender: TObject);
procedure MyDataSetFetchComplete(DataSet: TCustomADODataSet; const Error: Error; var EventStatus: TEventStatus);
private
{ Private-Deklarationen }
Procedure ConnectDatasource(var MSG:TMessage); message WM_MYConnect;
public
{ Public-Deklarationen }
end;
var
MyForm: TMyForm;
implementation
{$R *.dfm}
procedure TMyForm.Button1Click(Sender: TObject);
begin
MyDataset.Close;
// example blocking command for SQL-Server 10 seconds
MyDataset.CommandText := 'WAITFOR DELAY ''00:00:10'' Select* from aa';
Mydataset.DisableControls;
Mydataset.ExecuteOptions := [eoAsyncExecute,eoAsyncFetch];
MyDataset.Open;
end;
procedure TMyForm.ConnectDatasource(var MSG:TMessage);
begin
TAdodataset(MSG.WParam).EnableControls;
// MyDataSource.DataSet := MyDataset;
end;
procedure TMyForm.MyDataSetFetchComplete(DataSet: TCustomADODataSet; const Error: Error; var EventStatus: TEventStatus);
begin
// if we want to add a datasource we will have to ensure that it will happen after leaving FetchComplete
// so we call our procedure ConnectDatasource via PostMessage
PostMessage(Handle,WM_MYConnect,wParam(DataSet),0);
end;
end.