请教一个非常简单的线程问题!(10分)

  • 主题发起人 易名烦
  • 开始时间

易名烦

Unregistered / Unconfirmed
GUEST, unregistred user!
这是我的代码:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TMyThread = Class(TThread)
procedure SetText;
procedure Execute;
Override;
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
MThread: TMyThread;
begin
Mthread := TMyThread.Create(false);
end;

{ TMyThread }
procedure TMyThread.Execute;
begin
Self.FreeOnTerminate := true;
Synchronize(SetText);
end;

procedure TMyThread.SetText;
begin
While Form1.Memo1.Lines.Count > 10do
Form1.Button1.Caption := 'Thread Over!';
end;

end.
问:为何我在MEMO1中输入数超过十行BUTTON的CAPTION却不变?
我测试了一下,好象WHILE循环没起作用,跟本就没循环。
 
你的线程根本就没有创建!另外,代码也有问题。按你的写法,代码只会运行一遍。
var
s:TMythread;
begin
s:=TMyThread.Create(False);
...
s.Execute;
....
s.Terminate;
....(等线程结束)
s.Free;
end;

procedure TMyThread.Execute;
begin
While not Terminateddo
begin
Form1.ProcessMessages;
Synchronize(SetText);
end;
end
 
Mthread := TMyThread.Create(false);
这一句在创建完线程后会自动执行。
我试试这个,也许是解决问题之所在。
While not Terminateddo
begin
Form1.ProcessMessages;
Synchronize(SetText);
end;
 
问题是解决了,但变成死循环了。
线程始终没结束,始终在给BUTTON1的CAPTION赋值。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TMyThread = Class(TThread)
procedure SetText;
procedure Execute;
Override;
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
MThread: TMyThread;
begin
Mthread := TMyThread.Create(false);
end;

{ TMyThread }
procedure TMyThread.Execute;
begin
Self.FreeOnTerminate := true;
While not Terminateddo
Synchronize(SetText);
end;

procedure TMyThread.SetText;
begin
While Form1.Memo1.Lines.Count > 10do
Form1.Button1.Caption := 'Thread Over!';
end;

end.
 
不会我要改成:
procedure TMyThread.SetText;
begin
While Form1.Memo1.Lines.Count > 10do
begin
Form1.Button1.Caption := 'Thread Over!';
Terminate;
end;
end;
 
你明白了!
 
不得行啊,我写成上面的代码也不得行。
 
给你一段我的代码看看,应该有帮助的
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
ttest = class(tthread)
private
procedure fs;
protected
procedure execute;
override;
public
constructor create;
destructor destroy;override;
end;

TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
uses Unit2, Unit3;
{$R *.dfm}
constructor ttest.create;
begin
inherited create(false);
freeonterminate := true;
end;

destructor ttest.destroy;
begin
inherited destroy;
end;

procedure ttest.execute;
begin
Synchronize(fs);
while 1 = 1do
if form1.Button2.Enabled then
break;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
test: ttest;
begin
button2.Enabled := false;
test := ttest.create;
end;

procedure ttest.fs;
begin
form2.Show;
end;

end.
 
干嘛非要这样,书上没这样讲啊。
能讲讲原因吗?
 
怎么还不明白?
procedure TMyThread.Execute;
begin
While not Terminateddo
begin
Form1.ProcessMessages;
Synchronize(SetText);
If Form1.Memo1.Lines.Count > 10 then
Terminate;
end;
end
 
不明白,线程非要人为写代码终止吗?
书上说过了,线程可以自已终止并自己清除内存。
firstrose:
就算我写成你的代码,也不会退出。
 
晕,synchronize呀,此时线程和主进程是同步的,即运行synchronize时主进程没机会运行自己的代码, 看看你的代码就知道了,线程中本来就是一个没有任何等待时间的高速死循环,而且是阻塞住主进程来执行的。不死才怪
 
不好意思,我刚学进程,麻烦给讲一下要怎么做才正确。
顺便讲讲把线程运行的机制讲一讲要得不?
 
我是否要把控制权交给主进程,要怎么做?
 
不就是希望memo1行数超过10时把button1的caption换掉吗?
procedure TMyThread.execute;
begin
While not Terminateddo
begin
Synchronize(SetText);
sleep(1000);
// 1秒钟执行一次
end;
end;

procedure TMyThread.SetText;
begin
if Form1.Memo1.Lines.Count > 10 then
Form1.Button1.Caption := 'Thread Over!';
end
 
Another_eYes:
对了,为何WHILE会死呢?
 
啊,抱歉,应该是Application.ProcessMessages;
有这个用while就不死了。
 
不对,因为Synchronize中的"过程"是切换到主进程中进行的,
所以你在线程里这样用等于根本没用进程进行处理.
我想这个原理在你的书上应该是说有的.
 
当我们在应用程序中创建第二个线程的一霎那,VCL在主线程环境中创建并维护一个隐藏的线程窗口。这个窗口的惟一目的是串行化通过Synchronize()方法调用的执行过程。
其中Synchronize()把Method参数中的特定方法存储在一个名为Fmethod的私有或中,并且发送一条VCL定义的CM_EXECPROC消息到线程窗口中,该消息的lParam值填入的是Self(Self是TThread对象实例句柄)。当线程窗口的窗口过程接受到CM_EXECPROC消息后,它通过lParam中指定的TThread对象实例调用FMethod中指定的方法。记住,由于线程窗口是从主线程环境中建立的,它的窗口过程也是由主线程执行的。这样,FMethod中指定的方法也是由主线程执行的。
[red]理解不通啊,帮忙!!!!![/red]
 

Similar threads

回复
3
查看
279
迷惘的人
Q
回复
4
查看
298
穿越沦陷的爱
穿
C
回复
9
查看
215
coolingxyz
C
顶部