gpt4 book ai didi

multithreading - Delphi线程异常机制

转载 作者:行者123 更新时间:2023-12-03 14:36:14 24 4
gpt4 key购买 nike

我对线程在delphi中如何工作以及为什么在线程应该引发异常的时刻没有显示异常感到困惑。下面是带注释的代码,也许有人可以向我解释该线程或delphi如何管理访问冲突

//线程代码

unit Unit2;

interface

uses
Classes,
Dialogs,
SysUtils,
StdCtrls;

type
TTest = class(TThread)
private
protected
j: Integer;
procedure Execute; override;
procedure setNr;
public
aBtn: tbutton;
end;

implementation


{ TTest }

procedure TTest.Execute;
var
i : Integer;
a : TStringList;
begin
// make severals operations only for having something to do
j := 0;
for i := 0 to 100000000 do
j := j + 1;
for i := 0 to 100000000 do
j := j + 1;
for i := 0 to 100000000 do
j := j + 1;
for i := 0 to 100000000 do
j := j + 1;
for i := 0 to 100000000 do
j := j + 1;
for i := 0 to 100000000 do
j := j + 1;
for i := 0 to 100000000 do
j := j + 1;
for i := 0 to 100000000 do
j := j + 1;

Synchronize(setnr);
a[2] := 'dbwdbkbckbk'; //this should raise an AV!!!!!!

end;

procedure TTest.setNr;
begin
aBtn.Caption := IntToStr(j)
end;

end.

项目代码

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
public
nrthd:Integer;
acrit:TRTLCriticalSection;
procedure bla();
procedure bla1();
function bla2():boolean;
procedure onterm(Sender:TObject);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.bla;
begin
try
bla1;
except on e:Exception do
ShowMessage('bla '+e.Message);
end;
end;

procedure TForm1.bla1;
begin
try
bla2
except on e:Exception do
ShowMessage('bla1 '+e.Message);
end;
end;

function TForm1.bla2: boolean;
var ath:TTest;
begin
try
ath:=TTest.Create(true);
InterlockedIncrement(nrthd);
ath.FreeOnTerminate:=True;
ath.aBtn:=Button1;
ath.OnTerminate:=onterm;
ath.Resume;
except on e:Exception do
ShowMessage('bla2 '+e.Message);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);

begin
//
try
bla;
while nrthd>0 do
Application.ProcessMessages;
except on e:Exception do
ShowMessage('Button1Click '+e.Message);
end;
ShowMessage('done with this');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
nrthd:=0;
end;

procedure TForm1.onterm(Sender: TObject);
begin
InterlockedDecrement(nrthd)
end;

end.

此应用程序的目的只是了解在哪里捕获访问冲突,以及应如何编写代码。
我不明白为什么在“a[2] := 'dbwdbkbckbk';”行中AV 未升高。

最佳答案

在 Delphi 2005(可能还有大多数其他版本)中,如果异常从 Execute 方法中逃逸而没有得到处理,则它会被调用 Execute 的函数捕获,并且存储在线程的 FatalException 属性中。 (查看Classes.pasThreadProc。)在释放线程之前,不会对该异常执行任何进一步操作,此时异常也被释放。

因此,您有责任检查该属性并采取措施。您可以在线程的 OnTerminate 处理程序中检查它。如果它非空,则线程由于未捕获的异常而终止。因此,例如:

procedure TForm1.onterm(Sender: TObject);
var
ex: TObject;
begin
Assert(Sender is TThread);
ex := TThread(Sender).FatalException;
if Assigned(ex) then begin
// Thread terminated due to an exception
if ex is Exception then
Application.ShowException(Exception(ex))
else
ShowMessage(ex.ClassName);
end else begin
// Thread terminated cleanly
end;
Dec(nrthd);
end;

无需使用互锁函数来跟踪线程数。您的线程创建函数和终止处理程序始终在主线程的上下文中运行。普通的旧 IncDec 就足够了。

关于multithreading - Delphi线程异常机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3627743/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com