DELPHI6中使用Synchronize的问题

时间:2021-07-08 17:33:53
为什么在DELPHI6中使用TThread的Synchronize方法执行TThread的方法时程序就不报错的死在那里了啊?
比如它帮助里的例子:
procedure TMyThread.PushTheButton;

begin
  Button1.Click();
end;

procedure TMyThread.Execute;
begin
...
  Synchronize(PushTheButton);
  ...
end;
运行到Synchronize(PushTheButton)时程序就停留在那里不动了啊?

13 个解决方案

#1


补充:同样的语句在DELPHI5中可以执行!

#2


当然错了!TMyThread中不会有Button1吧!那就应该加上所属的类!如
Form1.Button1.Click();

#3


楼上的:这我知道,那些都在USES中加入了,主要问题是同样的代码在DELPHI6中执行正常,但到了DELPHI6中遇到Synchronize方法的调用程序就死了,没有任何错误提示!

#4


改成函数调用!如:
Form1.Button1Click();

#5


楼上的:跟Button没关系的,我在TMyThread中使用其他方法也是到那里就死了,你不信自己试了看!

#6


不明白!Button1.Click();这也能编译通过???
既然Button1是在Form1中定义的,那么前面一定要加Form1!
其它代码并无错误!也绝对可以这样用!

#7


试一下:Form1.Button1Click(nil);还有你的button1的事件没有逻辑问题,比如死循环的

#8


不关BUTTON的事,写其它语句,比如PANEL,PROGRESS等也是这样的问题!

#9


PANEL,PROGRESS都是Form中定义的!
所以是
Form1.Panel
Form1.Progress
你的
Button1.Click();
编译不出错?

#10


实在不行改成向按钮发送消息实现点击!

#11


要不帖出完整代码来看看!

#12


以下是源代码,窗体上只是简单的一个PROGRESSBAR和一个BUTTON,在DELPHI中执行时PROGRESSBAR可以滚动,到了DELPHI6时,执行到Synchronize(InitProgressBar)时程序便死掉了,没有任何错误提示!
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants,Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Bar: TProgressBar;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    private
    { Private declarations }
    public
    { Public declarations }
  end;
  TWorkProgress = class(TThread)
  private
    { Private declarations }
    PB : TProgressBar;              // Reference to ProgressBar
    FMax : integer;
    procedure InitProgressBar;      // Setup ProgressBar
    procedure UpdateProgressBar;    // Update ProgressBar
    procedure FinishIt;
  protected
    procedure Execute; override;
  public
     constructor CreateIt(ProgressBar: TProgressBar; TheMax: integer);
  end;


var
  Form1: TForm1;
   ProgressThread:TWorkProgress;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  Max:Integer;
begin
  Max:=10000;
  ProgressThread:=nil;
   if ProgressThread = nil then
  begin
    if Bar = nil then
      ProgressThread := TWorkProgress.CreateIt(Bar as TProgressBar,Max)
    else
      ProgressThread := TWorkProgress.CreateIt(Bar,Max);
  end;
end;

{ TWorkProgress }

constructor TWorkProgress.CreateIt(ProgressBar: TProgressBar;
  TheMax: integer);
begin
  inherited Create(True);
  Priority := tpLowest;//tpNormal;
  FreeOnTerminate := True;
  PB := ProgressBar;
  FMax := TheMax;
  Synchronize(InitProgressBar);
  Suspended := False;
end;

procedure TWorkProgress.Execute;
begin
  { Place thread code here }

  while not Terminated do
  begin
    Synchronize(UpdateProgressBar);
  end;
  Synchronize(FinishIt);
end;

procedure TWorkProgress.FinishIt;
begin
  if (PB.Position > PB.Min) and (PB.Position < PB.Max) then
  begin
    Priority := tpHighest; //tpTimeCritical;
    PB.Step := (PB.Max - PB.Position) div 100;
    if PB.Step < 1 then PB.Step := 1;
    while PB.Position + PB.Step < PB.Max do
      PB.StepIt;
  end;
  PB.Position := PB.Min;
end;

procedure TWorkProgress.InitProgressBar;

begin
  PB.Min := 0;
  PB.Max := FMax;//10000;
  PB.Step := 1;
  PB.Position := 1;    
end;

procedure TWorkProgress.UpdateProgressBar;
begin
  if PB.Position < PB.Max then
    PB.StepIt
  else
    PB.Position := PB.Min;
end;

end.

#13


DELPHI提供的例子:DELPHI6\Help\Examples\PrgrsBar也发生了同样的问题!

#1


补充:同样的语句在DELPHI5中可以执行!

#2


当然错了!TMyThread中不会有Button1吧!那就应该加上所属的类!如
Form1.Button1.Click();

#3


楼上的:这我知道,那些都在USES中加入了,主要问题是同样的代码在DELPHI6中执行正常,但到了DELPHI6中遇到Synchronize方法的调用程序就死了,没有任何错误提示!

#4


改成函数调用!如:
Form1.Button1Click();

#5


楼上的:跟Button没关系的,我在TMyThread中使用其他方法也是到那里就死了,你不信自己试了看!

#6


不明白!Button1.Click();这也能编译通过???
既然Button1是在Form1中定义的,那么前面一定要加Form1!
其它代码并无错误!也绝对可以这样用!

#7


试一下:Form1.Button1Click(nil);还有你的button1的事件没有逻辑问题,比如死循环的

#8


不关BUTTON的事,写其它语句,比如PANEL,PROGRESS等也是这样的问题!

#9


PANEL,PROGRESS都是Form中定义的!
所以是
Form1.Panel
Form1.Progress
你的
Button1.Click();
编译不出错?

#10


实在不行改成向按钮发送消息实现点击!

#11


要不帖出完整代码来看看!

#12


以下是源代码,窗体上只是简单的一个PROGRESSBAR和一个BUTTON,在DELPHI中执行时PROGRESSBAR可以滚动,到了DELPHI6时,执行到Synchronize(InitProgressBar)时程序便死掉了,没有任何错误提示!
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants,Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Bar: TProgressBar;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    private
    { Private declarations }
    public
    { Public declarations }
  end;
  TWorkProgress = class(TThread)
  private
    { Private declarations }
    PB : TProgressBar;              // Reference to ProgressBar
    FMax : integer;
    procedure InitProgressBar;      // Setup ProgressBar
    procedure UpdateProgressBar;    // Update ProgressBar
    procedure FinishIt;
  protected
    procedure Execute; override;
  public
     constructor CreateIt(ProgressBar: TProgressBar; TheMax: integer);
  end;


var
  Form1: TForm1;
   ProgressThread:TWorkProgress;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  Max:Integer;
begin
  Max:=10000;
  ProgressThread:=nil;
   if ProgressThread = nil then
  begin
    if Bar = nil then
      ProgressThread := TWorkProgress.CreateIt(Bar as TProgressBar,Max)
    else
      ProgressThread := TWorkProgress.CreateIt(Bar,Max);
  end;
end;

{ TWorkProgress }

constructor TWorkProgress.CreateIt(ProgressBar: TProgressBar;
  TheMax: integer);
begin
  inherited Create(True);
  Priority := tpLowest;//tpNormal;
  FreeOnTerminate := True;
  PB := ProgressBar;
  FMax := TheMax;
  Synchronize(InitProgressBar);
  Suspended := False;
end;

procedure TWorkProgress.Execute;
begin
  { Place thread code here }

  while not Terminated do
  begin
    Synchronize(UpdateProgressBar);
  end;
  Synchronize(FinishIt);
end;

procedure TWorkProgress.FinishIt;
begin
  if (PB.Position > PB.Min) and (PB.Position < PB.Max) then
  begin
    Priority := tpHighest; //tpTimeCritical;
    PB.Step := (PB.Max - PB.Position) div 100;
    if PB.Step < 1 then PB.Step := 1;
    while PB.Position + PB.Step < PB.Max do
      PB.StepIt;
  end;
  PB.Position := PB.Min;
end;

procedure TWorkProgress.InitProgressBar;

begin
  PB.Min := 0;
  PB.Max := FMax;//10000;
  PB.Step := 1;
  PB.Position := 1;    
end;

procedure TWorkProgress.UpdateProgressBar;
begin
  if PB.Position < PB.Max then
    PB.StepIt
  else
    PB.Position := PB.Min;
end;

end.

#13


DELPHI提供的例子:DELPHI6\Help\Examples\PrgrsBar也发生了同样的问题!