我习惯于执行像这样的匿名线程:
TThread.CreateAnonymousThread(
procedure
begin
.....
end).start;
但是问题是,如果在执行过程中出现某些未处理异常,则不会警告我!对于主线程,我们有Application.OnException
。我们的后台线程有类似的东西吗?
答案 0 :(得分:11)
TThread
具有公共FatalException
属性:
如果
Execute
方法引发该方法中未捕获和处理的异常,则线程终止并将FatalException
设置为该异常的异常对象。 应用程序可以从OnTerminate
事件处理程序中检查FatalException
,以确定线程是否由于异常而终止。
例如:
procedure TMyForm.DoSomething;
begin
...
thread := TThread.CreateAnonymousThread(...);
thread.OnTerminate := ThreadTerminated;
thread.Start;
...
end;
procedure TMyForm.ThreadTerminated(Sender: TObject);
begin
if TThread(Sender).FatalException <> nil then
begin
...
end;
end;
答案 1 :(得分:5)
N̶o̶,̶̶t̶h̶e̶r̶e̶̶i̶s̶̶n̶o̶t̶h̶i̶n̶g̶̶s̶i̶m̶i̶l̶a̶r̶̶f̶o̶r̶̶a̶̶b̶a̶c̶k̶g̶r̶o̶u̶n̶dhanhant,()
最好的解决方案是始终绝对确保永远不要让异常从线程中逸出。理想情况下,您的线程过程应如下所示:
TThread.CreateAnonymousThread(
procedure
begin
try
{ your code}
except
{on E : Exception do}
{... handle it!}
end;
end).start;
答案 2 :(得分:1)
Ok, finally I got the best answer :
Assign the global ExceptionAcquired
procedure to our own implementation (it is nil by default). This procedure gets called for unhandled exceptions that happen in other threads than the main thread.
ExceptionAcquired := MyGlobalExceptionAcquiredHandler;
答案 3 :(得分:-1)
J ...和雷米·勒博(Remy Lebeau)的回答对delphi提供的功能很满意,但我还需要更多,所以我最终决定对System.Classes
单位进行一些修改。
var
ApplicationHandleThreadException: procedure (Sender: TObject; E: Exception) of object = nil;
function ThreadProc(const Thread: TThread): Integer;
...
try
Thread.Execute;
except
Thread.FFatalException := AcquireExceptionObject;
if assigned(ApplicationHandleThreadException) and
assigned(Thread.FFatalException) and
(Thread.FFatalException is Exception) and
(not (Thread.FFatalException is EAbort)) then
ApplicationHandleThreadException(Thread, Exception(Thread.FFatalException));
end;
通过这种方式,您只需要分配ApplicationHandleThreadException
即可处理任何TThread中未处理的异常引发。您不必担心多线程,因为像ExceptAddr
这样的全局var被声明为threadvar
,因此一切工作正常,甚至可以检索堆栈跟踪!