如何在单独的线程(不同的主线程)中打开ClientDataSet(主/详细信息)

时间:2012-12-30 19:27:23

标签: multithreading delphi firebird datasnap dbexpress

使用:Delphi XE2,DBExpress,Firebird

我无法安全访问主线程外的任何VCL控件,包括表单,面板,编辑等以及Timage和Timage后代。我需要在单独的线程(不同的主线程)中打开ClientDataSet(主/细节)。

我需要在访问数据库时创建动画启动画面

有人能告诉我一个如何做到这一点的简单例子吗?

1 个答案:

答案 0 :(得分:2)

我假设线程中的数据库访问对你来说没问题。

有关对dbExpress数据库的线程访问的完整示例(包括对主线程的反馈),请参阅Marco Cantù在此处创建的示例:dbexpress_firebird_examples

它涉及将所有数据库连接设置放在TDataModule中,并为每个线程访问创建此数据模块的实例。

反正 使用动画Gif向GUI通知后台线程进程,这是一个例子:

enter image description here

unit TestAnimatedScreen;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Imaging.GIFImg,
  Vcl.ExtCtrls;

type
  TMyEndNotify = procedure (value: Boolean) of object;

type
  TMyThread = class(TThread)
  private
    fEndNotification : TMyEndNotify;
    procedure NotifyEndOfThread;
  protected
    procedure Execute; override;
  public
    Constructor Create(endNotification : TMyEndNotify);
  end;

type
  TMainForm = class(TForm)
    Image1: TImage;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    FShowAnimation : Boolean;
    procedure SetShowAnimation(value : Boolean);
  public
    { Public declarations }
    property ShowAnimation : Boolean read FShowAnimation write SetShowAnimation;
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

procedure TMyThread.NotifyEndOfThread;
begin
  if Assigned(fEndNotification) then
    fEndNotification(False);
end;

constructor TMyThread.Create(endNotification: TMyEndNotify);
begin
  Inherited Create(false);
  fEndNotification := endNotification;
  Self.FreeOnTerminate := True; // Free automatically
end;

procedure TMyThread.Execute;
begin
  try
    {Add your database access code here}
    Sleep(5000); // Simulate lengthy process
  finally
    Synchronize(NotifyEndOfThread);
  end;
end;

{ TMainForm }

procedure TMainForm.Button1Click(Sender: TObject);
begin
  ShowAnimation := True;
  TMyThread.Create(Self.SetShowAnimation);
end;

procedure TMainForm.SetShowAnimation(value: Boolean);
begin
  FShowAnimation := Value;
  if FShowAnimation then
  begin
    {Add animation code here}
    Button1.Enabled := false;
    Button1.Caption := 'Processing, please wait ...';
    (Image1.Picture.Graphic as TGIFImage).AnimateLoop := glEnabled;
    (Image1.Picture.Graphic as TGIFImage).Animate := true;
  end
  else
  begin
    {Stop animation}
    (Image1.Picture.Graphic as TGIFImage).Animate := false;
    Button1.Caption := 'Start lengthy process';
    Button1.Enabled := True;
  end;
end;

end.

object MainForm: TMainForm
  Left = 0
  Top = 0
  Caption = 'MainForm'
  ClientHeight = 265
  ClientWidth = 236
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Image1: TImage
    Left = 8
    Top = 8
    Width = 200
    Height = 200
    AutoSize = True
    IncrementalDisplay = True
  end
  object Button1: TButton
    Left = 8
    Top = 224
    Width = 200
    Height = 25
    Caption = 'Start lengthy process'
    TabOrder = 0
    OnClick = Button1Click
  end
end

如果你有比Delphi 2007更旧的Delphi版本,请参阅How to use Animated Gif in a delphi form以获取有关如何实现动画GIF的更多信息。

我使用的动画GIF可以找到here