N
neom
Unregistered / Unconfirmed
GUEST, unregistred user!
简单的线程程序:
unit unitMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
procedure ThreadDone(sender: TObject);
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses unitThread;
{$R *.dfm}
var
ThreadRuning:integer;
MyThread1:TestThread;
MyThread2:TestThread;
procedure TForm1.Button1Click(Sender: TObject);
begin
ThreadRuning:=2;
MyThread1:=TestThread.Create(Edit1,10000);
MyThread1.OnTerminate:=ThreadDone;
MyThread2:=TestThread.Create(Edit2,10000);
MyThread2.OnTerminate:=ThreadDone;
Button1.enabled:=false;
end;
procedure TForm1.ThreadDone(Sender: TObject);
begin
dec(ThreadRuning);
if ThreadRuning=0 then
Button1.enabled:=true;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if MyThread1<>nil then
try
MyThread1.Terminate;
MyThread1.WaitFor;
//MyTHread1.Free;
//MyThread1:=nil
except
showmessage('freed');
end;
end;
end.
unit unitThread;
interface
uses
Classes, StdCtrls, SysUtils {$IFDEF MSWINDOWS} , Windows {$ENDIF};
type
TestThread = class(TThread)
private
AEdit:TEdit;
MaxLoop:integer;
CurrentLoop:integer;
procedure SetName;
protected
procedure Execute;
override;
procedure DisLoop;
public
constructor Create(Edit:TEdit;Max:integer);
end;
implementation
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure TestThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
{$IFDEF MSWINDOWS}
type
TThreadNameInfo = record
FType: LongWord;
// must be 0x1000
FName: PChar;
// pointer to name (in user address space)
FThreadID: LongWord;
// thread ID (-1 indicates caller thread)
FFlags: LongWord;
// reserved for future use, must be zero
end;
{$ENDIF}
{ TestThread }
constructor TestThread.Create(Edit:TEdit;Max:integer);
begin
inherited Create(false);
AEdit:=Edit;
MaxLoop:=Max;
FreeOnTerminate:=true;
end;
procedure TestThread.SetName;
{$IFDEF MSWINDOWS}
var
ThreadNameInfo: TThreadNameInfo;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
ThreadNameInfo.FType := $1000;
ThreadNameInfo.FName := 'tmpThread';
ThreadNameInfo.FThreadID := $FFFFFFFF;
ThreadNameInfo.FFlags := 0;
try
RaiseException( $406D1388, 0, sizeof(ThreadNameInfo) div sizeof(LongWord), @ThreadNameInfo );
except
end;
{$ENDIF}
end;
procedure TestThread.Execute;
var
i:integer;
begin
SetName;
{ Place thread code here }
for i:=0 to MaxLoopdo
begin
CurrentLoop:=i;
Synchronize(DisLoop);
if terminated then
exit;
end;
end;
procedure TestThread.DisLoop;
begin
AEdit.Text:=IntToStr(CurrentLoop);
end;
end.
F9运行时点start 然后点terminate
出现如下错误:
raise exception error with message 'Thread error 句柄无效。(6)'
unit unitMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
procedure ThreadDone(sender: TObject);
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses unitThread;
{$R *.dfm}
var
ThreadRuning:integer;
MyThread1:TestThread;
MyThread2:TestThread;
procedure TForm1.Button1Click(Sender: TObject);
begin
ThreadRuning:=2;
MyThread1:=TestThread.Create(Edit1,10000);
MyThread1.OnTerminate:=ThreadDone;
MyThread2:=TestThread.Create(Edit2,10000);
MyThread2.OnTerminate:=ThreadDone;
Button1.enabled:=false;
end;
procedure TForm1.ThreadDone(Sender: TObject);
begin
dec(ThreadRuning);
if ThreadRuning=0 then
Button1.enabled:=true;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if MyThread1<>nil then
try
MyThread1.Terminate;
MyThread1.WaitFor;
//MyTHread1.Free;
//MyThread1:=nil
except
showmessage('freed');
end;
end;
end.
unit unitThread;
interface
uses
Classes, StdCtrls, SysUtils {$IFDEF MSWINDOWS} , Windows {$ENDIF};
type
TestThread = class(TThread)
private
AEdit:TEdit;
MaxLoop:integer;
CurrentLoop:integer;
procedure SetName;
protected
procedure Execute;
override;
procedure DisLoop;
public
constructor Create(Edit:TEdit;Max:integer);
end;
implementation
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure TestThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
{$IFDEF MSWINDOWS}
type
TThreadNameInfo = record
FType: LongWord;
// must be 0x1000
FName: PChar;
// pointer to name (in user address space)
FThreadID: LongWord;
// thread ID (-1 indicates caller thread)
FFlags: LongWord;
// reserved for future use, must be zero
end;
{$ENDIF}
{ TestThread }
constructor TestThread.Create(Edit:TEdit;Max:integer);
begin
inherited Create(false);
AEdit:=Edit;
MaxLoop:=Max;
FreeOnTerminate:=true;
end;
procedure TestThread.SetName;
{$IFDEF MSWINDOWS}
var
ThreadNameInfo: TThreadNameInfo;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
ThreadNameInfo.FType := $1000;
ThreadNameInfo.FName := 'tmpThread';
ThreadNameInfo.FThreadID := $FFFFFFFF;
ThreadNameInfo.FFlags := 0;
try
RaiseException( $406D1388, 0, sizeof(ThreadNameInfo) div sizeof(LongWord), @ThreadNameInfo );
except
end;
{$ENDIF}
end;
procedure TestThread.Execute;
var
i:integer;
begin
SetName;
{ Place thread code here }
for i:=0 to MaxLoopdo
begin
CurrentLoop:=i;
Synchronize(DisLoop);
if terminated then
exit;
end;
end;
procedure TestThread.DisLoop;
begin
AEdit.Text:=IntToStr(CurrentLoop);
end;
end.
F9运行时点start 然后点terminate
出现如下错误:
raise exception error with message 'Thread error 句柄无效。(6)'