我的应用程序中有一个处理生成的异常的过程。事实证明,如果在 untThreadDSR 中生成异常,则异常不会被它应该操作它的过程捕获。如果异常是从任何其他表单生成的,则该过程会正确捕获它。
该过程位于主DataModule中:
...
private
{ Private declarations }
procedure HandleExceptions(Sender: TObject; E: Exception);
...
procedure DM.HandleExceptions(Sender: TObject; E: Exception);
begin
if pos('UNIQUE KEY',E.Message) <> 0 then
begin
if pos('UNQ_CUSTOMER_NAME',E.Message) <> 0 then
MsgMsg('Customer already registered.',2)
else if pos('UNQ_USERS_LOGIN',E.Message) <> 0 then
MsgMsg('User already registered.',2);
end else
if pos('ERROR_DATASYS',E.Message) <> 0 then
MsgMsg('The Server Date is incorrect. Please contact your network administrator!',2)
else //Other messages will be sent to Support
SendReport(E.Message, V_COMPANY, V_LOGIN, V_APP_VERSION, Sender);
end;
untThreadDSR:
unit untThreadDSR;
interface
uses
Classes, SysUtils, Messages, Windows, Forms;
type
TThreadDSR = class(TThread)
procedure DSR_Start;
private
{ Private declarations }
protected
procedure Execute; override;
end;
implementation
uses untDM;
procedure TThreadDSR.DSR_Start;
begin
//I put this intentionally just to generate an exception
StrToInt('');
//If this is on any other form, the exception is caught by "HandleExceptions", but from here on out!
end;
procedure TThreadDSR.Execute;
begin
Synchronize(DSR_Start);
end;
end.
TThreadDSR的调用方式如下:
procedure TFrmDSR.btnExecuteClick(Sender: TObject);
var
Thread: TThreadDSR;
begin
Thread := TThreadDSR.Create(true);
Thread.FreeOnTerminate := true;
Thread.Resume;
end;
答案 0 :(得分:2)
异常不跨越线程边界。如果未捕获的异常转义TThread.Synchronize()
调用的过程,Synchronize()
将捕获异常并在工作线程的上下文中重新引发它。如果Execute()
随后未捕获异常,则线程将终止并将异常分配给TThread.FatalException
属性。
您可以使用TThread.OnTerminate
事件(在主线程的上下文中调用)将FatalException
传递给您的HandleExceptions()
程序。