利用TThread时,在win2000下无法正常运行(200分)

  • 主题发起人 主题发起人 woodea
  • 开始时间 开始时间
W

woodea

Unregistered / Unconfirmed
GUEST, unregistred user!
[^][blue][/blue]我利用TThread写了一个多线程的小例子。就是在一个窗口里,用两个新生成的线程让两个进度条循环往复。
如果在win98下,运行完全正常,但在win2000下,如果我首先让一个进度条运行起来,则可以拖动窗体,即窗口仍然能够接收消息,但如果我再让另外一个进度条运行起来,这时窗口就无法再响应鼠标或键盘事件。
我是在win2000下用delphi5.0(已经装了补丁程序)编译的。后来用delphi6.0编译,仍然是这样。
哪位高手能指点迷津?
如果感兴趣,可以发邮件给我,我可以把那个例子的原代码给你。
 
详细的代码了?我做的类似的东西没有问题啊
 
贴上来看看吧,俺现在有空,应该是小问题
 
//==========================mythread.pas=================//
unit mythread;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
p1: TProgressBar;
p2: TProgressBar;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Button6: TButton;
Button7: TButton;
Edit1: TEdit;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

T1 = class( TThread)
public
constructor create( thebar: Tprogressbar);
protected
procedure execute;
override;
private
fbar: Tprogressbar;
end;

T2 = class( TThread)
public
constructor create( theedit: TEdit);
protected
procedure execute;
override;
private
fedit: Tedit;
proceduredo
loop;
end;

var
Form1: TForm1;
Ta,Tb: T1;
//ta, Tb: T2;
implementation
{$R *.DFM}
constructor T1.create( thebar: Tprogressbar);
begin
inherited create( true);
fbar:= thebar;
end;

Procedure T1.execute;
begin
repeat
synchronize( fbar.StepIt);
if fbar.Position>= fbar.Max then
fbar.position:=fbar.min;
until terminated;
end;

constructor T2.create( theedit: TEdit);
begin
inherited create( true);
fedit:= theedit;
fedit.Text:='0';
end;

Procedure T2.execute;
begin
repeat
synchronize(do
loop);
if strtoint(fedit.Text)>=10000 then
fedit.Text:= '0';
until terminated;
end;

procedure T2.doloop;
begin
fedit.Text:=inttostr( strtoint( fedit.text)+1);
end;

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

procedure TForm1.Button2Click(Sender: TObject);
begin
ta.Suspend;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
ta.Terminate;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
tb.Resume;
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
tb.Suspend;
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
tb.Terminate;
end;

procedure TForm1.Button7Click(Sender: TObject);
begin
ta:=t1.create( p1);
tb:=t1.create( p2);
end;

end.
//======================end of mythread.pas==================//
//======================mythread.dfm=========================//
object Form1: TForm1
Left = 192
Top = 107
Width = 544
Height = 375
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 272
Top = 64
Width = 75
Height = 25
Caption = 'resume'
TabOrder = 0
OnClick = Button1Click
end
object p1: TProgressBar
Left = 96
Top = 64
Width = 150
Height = 16
Min = 0
Max = 1000
TabOrder = 1
end
object p2: TProgressBar
Left = 96
Top = 112
Width = 150
Height = 16
Min = 0
Max = 1000
TabOrder = 2
end
object Button2: TButton
Left = 352
Top = 64
Width = 75
Height = 25
Caption = 'suspend'
TabOrder = 3
OnClick = Button2Click
end
object Button3: TButton
Left = 440
Top = 64
Width = 75
Height = 25
Caption = 'teminate'
TabOrder = 4
OnClick = Button3Click
end
object Button4: TButton
Left = 272
Top = 104
Width = 75
Height = 25
Caption = 'resume'
TabOrder = 5
OnClick = Button4Click
end
object Button5: TButton
Left = 352
Top = 104
Width = 75
Height = 25
Caption = 'suspend'
TabOrder = 6
OnClick = Button5Click
end
object Button6: TButton
Left = 440
Top = 104
Width = 75
Height = 25
Caption = 'teminate'
TabOrder = 7
OnClick = Button6Click
end
object Button7: TButton
Left = 368
Top = 24
Width = 75
Height = 25
Caption = 'Button7'
TabOrder = 8
OnClick = Button7Click
end
object Edit1: TEdit
Left = 96
Top = 144
Width = 121
Height = 21
TabOrder = 9
Text = '0'
end
object Edit2: TEdit
Left = 96
Top = 184
Width = 121
Height = 21
TabOrder = 10
Text = '0'
end
end
//=======================end of mythread.dfm======================//
 

Procedure T2.execute;
begin
repeat
synchronize(do
loop);
if strtoint(fedit.Text)>=10000 then
fedit.Text:= '0';

// 加上
Sleep(0);
until terminated;
end;

Procedure T1.execute;
begin
repeat
synchronize( fbar.StepIt);
if fbar.Position>= fbar.Max then
fbar.position:=fbar.min;
// 加上
Sleep(0);
until terminated;
end;

或者是 Application.ProcessMessages;
不让你的CPU会死锁,这是我们的Windows,Java
就不会这样的。
 
if strtoint(fedit.Text)>=10000 then
fedit.Text:= '0';
上面的代码也要同步!
因为在线程中真有引用VCL控件,一般就要同步处理;
 

Procedure T1.execute;
begin
repeat
synchronize( fbar.StepIt);
if fbar.Position>= fbar.Max then
fbar.position:=fbar.min;
until terminated;
end;
改为:
Procedure T1.execute;
begin
repeat
synchronize(StepIt);
until terminated;
end;

Procedure T1.StepIt;
begin
fbar.StepIt;
if fbar.Position>= fbar.Max then
fbar.position:=fbar.min;
end;


Procedure T2.execute;
begin
repeat
synchronize(do
loop);
if strtoint(fedit.Text)>=10000 then
fedit.Text:= '0';
until terminated;
end;

procedure T2.doloop;
begin
fedit.Text:=inttostr( strtoint( fedit.text)+1);
end;
改为:

Procedure T2.execute;
begin
repeat
synchronize(do
loop);
until terminated;
end;

procedure T2.doloop;
begin
fedit.Text:=inttostr( strtoint( fedit.text)+1);
if strtoint(fedit.Text)>=10000 then
fedit.Text:= '0';
end;
 
我想各位老兄真的把问题简单化了。可能你们根本就没有在win2000下运行这个程序,否则你们就会发现你们出的主意都是无效的(我说的都是实话,没别的意思)。请各位老兄不妨一试。
问题的关键并不在synchronize上。如果在win98下,即使我根本不用synchronize也能正常运行。而在win2000下,即使我把整个过程都放在synchronize里执行,也还是老毛病。(我已经按老兄们的提议做了,还是不行)。
哪位能再给点高见,不胜感激。
在此谢过以上各位的提议。
 
应该是同一个问题:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=873837
 
'DragonPC_???'加上sleep(0)应该是可以的, 我有在win2000试过, 但我也觉得应可不要
加, 因为不存在要同步的必要, 为何要用sleep(0)为分享一下cpu呢, 线程本来就是时间片
轮转的, why? 我们再研究一下.
 
后退
顶部