本人第一次使用Delphi的线程,就是很简单的点按钮,然后启动一个线程
但是在点击按钮后,再关闭窗口就会出错,
如果线程还没执行完,我就关闭,会出现如下提示
Thread Error: 句柄无效(6)
执行完后,在关闭,会出现如下提示:
Access Violation at address *******
代码如下,请指点,谢谢
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;type
TThread1 = class(TThread)
protected
procedure Execute; override;
end; TForm1 = class(TForm)
Button1: TButton;
mmo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
t1: TThread1;
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
t1 := TThread1.Create(False);
end;{ TThread1 }procedure TThread1.Execute;
var
i: Integer;
begin
FreeOnTerminate := True;
try
for i := 0 to 9999 do
begin
Form1.mmo1.Lines.add(IntToStr(i));
end;
except end;
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
if Assigned(t1) then
begin
t1.Terminate;
FreeAndNil(t1);
end;
end;end.
但是在点击按钮后,再关闭窗口就会出错,
如果线程还没执行完,我就关闭,会出现如下提示
Thread Error: 句柄无效(6)
执行完后,在关闭,会出现如下提示:
Access Violation at address *******
代码如下,请指点,谢谢
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;type
TThread1 = class(TThread)
protected
procedure Execute; override;
end; TForm1 = class(TForm)
Button1: TButton;
mmo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
t1: TThread1;
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
t1 := TThread1.Create(False);
end;{ TThread1 }procedure TThread1.Execute;
var
i: Integer;
begin
FreeOnTerminate := True;
try
for i := 0 to 9999 do
begin
Form1.mmo1.Lines.add(IntToStr(i));
end;
except end;
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
if Assigned(t1) then
begin
t1.Terminate;
FreeAndNil(t1);
end;
end;end.
解决方案 »
- 请教一下SqlServer2005的连接方式有几种,各有什么优点,谢谢了
- 程序标题栏加入自己的菜单后菜单无法产生事件,为何?
- Access数据库插入数据发生的奇怪问题
- 正则表达式与html表格
- 高手们,你们好呀!!难题来啦!!!用心想吧。请问怎么实现有关通过代理访问三层的问题。
- 怎么刷新开始菜单或桌面,以及对修改后注册表进行刷新?谢谢
- 怎么在扫描图片后,转换成80*60大小,保存到数据库里
- 我经常在程序里面看见wparam:Wparam,lparam:Lparam,请问这两个变量是什么意思?
- 高手请帮忙:delphi 如何连接sybase sql anywhere5.0数据库
- 明天答辩,老师会问什么问题?
- 如何用DELPHI修改文件指定地址的数据?
- 恭喜二位新版主上任,散分
t1 := TThread1.Create(False);
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TThread1 = class(TThread)
private
FIndex: Integer;
procedure LinesAdd();
protected
procedure Execute; override;
end; TForm1 = class(TForm)
Button1: TButton;
mmo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
t1: TThread1;
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TThread1.LinesAdd();
begin
Form1.mmo1.Lines.add(IntToStr(FIndex));
end;procedure TThread1.Execute;
var
i: Integer;
begin
FreeOnTerminate := True;
for i := 0 to 9999 do
begin
if Terminated then break;
FIndex := i;
Synchronize(LinesAdd);
end;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
t1 := TThread1.Create(False);
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
if Assigned(t1) then t1.Terminate;
end;end.
begin
if Assigned(t1) then
begin
t1.Terminate;
t1.WaitFor;
t1 := nil;
end;
end;
LZ代码错误百出!
function ThreadProc(Thread: TThread): Integer;
var
FreeThread: Boolean;
begin
try
if not Thread.Terminated then
try
Thread.Execute;
except
Thread.FFatalException := AcquireExceptionObject;
end;
finally
FreeThread := Thread.FFreeOnTerminate;
Result := Thread.FReturnValue;
Thread.DoTerminate;
Thread.FFinished := True;
SignalSyncEvent;
if FreeThread then Thread.Free;
//
1.
由VCL以上代码可以看出在FreeOnTerminate为True时,当执行完毕线程后,会把堆内存释放,但并没有把栈指针清空,而LZ在窗口关闭时又进行了一次线程对象的Free,这样,即使你等线程正常处理完毕后,再关闭窗体仍然会出错的!
2.
在遇到线程中途退出时,应遵循循环等待并判断退出标识的策略,而不是中途无判断!
3.
操作VCL时无同步
{$IFDEF MSWINDOWS}
EndThread(Result);
{$ENDIF}
end;
end;