加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – FireDac冻结GUI

发布时间:2020-12-15 09:23:23 所属栏目:大数据 来源:网络整理
导读:我正在Delphi 10.1 Berlin下使用FireDac. 为了向用户显示数据,我使用像TDBEdit这样的数据感知控件. 我使用TFDQuery和TDataSource将它们与控件链接起来. 这有效,但需要一些时间来执行的长sql查询将冻结GUI. 我想知道如何在执行那些长时间运行的查询时阻止gui
我正在Delphi 10.1 Berlin下使用FireDac.

为了向用户显示数据,我使用像TDBEdit这样的数据感知控件.

我使用TFDQuery和TDataSource将它们与控件链接起来.

这有效,但需要一些时间来执行的长sql查询将冻结GUI.

我想知道如何在执行那些长时间运行的查询时阻止gui冻结.

我在考虑背景线程.

在维基上,我读到FireDac可以使用多线程:
http://docwiki.embarcadero.com/RADStudio/XE6/en/Multithreading_(FireDAC)

但是在embarcadero社区论坛thread Jeff Overcash写道:

One thing I didn’t see asked or Dmitry mention is you can not have
TDataSource or LiveBindings against your background threaded queries.
If you are background threading a query that displays the results you
should disconnect the LB or DataSource,open and fetch all the data
then re establish the connection.

Those two will be trying to move the cursor on you or querying the
buffer for display while the buffer is very volatile being moved
around in a different thread.

我想知道是否有人也使用FireDac并在表单上显示值可以帮助我在这里.

解决方法

下面的代码示例显示了从MSSql Server中检索记录的一种方法
在使用FireDAC的后台线程中.这省略了一些细节.例如,在实践中,而不是TQueryThreads Execute只打开一次然后终止查询,你可能希望线程的Execute包含一个while循环,在调用Synchronize之后它在信号量上等待,然后关闭/重新打开查询以根据需要随时更新主线程.

type

  TForm1 = class;

  TQueryThread = class(TThread)
  private
    FConnection: TFDConnection;
    FQuery: TFDQuery;
    FForm: TForm1;
  published
    constructor Create(AForm : TForm1);
    destructor Destroy; override;
    procedure Execute; override;
    procedure TransferData;
    property Query : TFDQuery read FQuery;
    property Connection : TFDConnection read FConnection;
    property Form : TForm1 read FForm;
  end;

  TForm1 = class(TForm)
    FDConnection1: TFDConnection;
    FDQuery1: TFDQuery;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    DBNavigator1: TDBNavigator;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  public
    QueryThread : TQueryThread;
  end;

[...]

constructor TQueryThread.Create(AForm : TForm1);
begin
  inherited Create(True);
  FreeOnTerminate := True;
  FForm := AForm;
  FConnection := TFDConnection.Create(Nil);
  FConnection.Params.Assign(Form.FDConnection1.Params);
  FConnection.LoginPrompt := False;

  FQuery := TFDQuery.Create(Nil);
  FQuery.Connection := Connection;
  FQuery.SQL.Text := Form.FDQuery1.SQL.Text;
end;

destructor TQueryThread.Destroy;
begin
  FQuery.Free;
  FConnection.Free;
  inherited;
end;

procedure TQueryThread.Execute;
begin
  Query.Open;
  Synchronize(TransferData);
end;

procedure TQueryThread.TransferData;
begin
  Form.FDQuery1.DisableControls;
  Form.FDQuery1.Data := Query.Data;
  Form.FDQuery1.EnableControls;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  QueryThread.Resume;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  QueryThread := TQueryThread.Create(Self);
end;

MJN关于书签的评论告诉你如何保留gui中的当前数据行位置.

顺便说一下,虽然我经常用TClientDataSets做到这一点,把这个答案放在一起是我第一次尝试使用FireDAC.在配置组件方面,我所做的只是将组件拖离Palette,按照您的预期将它们“连接在一起”,然后设置FDConnection的Params和FDQuery的Sql.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读