【问题标题】:Catch unhandled exceptions from a different thread捕获来自不同线程的未处理异常
【发布时间】:2014-02-04 17:15:56
【问题描述】:

我正在编写一个 IPC 应用程序。我想从进程 B 静默捕获异常,然后将异常详细信息作为字符串发送到进程 A。我能够从主线程捕获异常,但在从不同线程捕获异常时遇到问题。

procedure TForm1.ApplicationEvents1Exception(Sender: TObject; E: Exception);
begin
  SendExceptionToAnotherProcess(E.ToString);
end;

type
  AThread = class(TThread)
  protected
    procedure Execute; override;
  end;

procedure AThread.Execute; // Main thread cannot catch such runtime exception
var  uq1, uq2: UInt64;
     s1:       Single;
     d1:       Double;
begin
  uq1 := $9000000000000000;
  s1 := uq1;   // no problem here
  // exception class $C0000090 with message 'c0000090 FLOAT_INVALID_OPERATION'.
  uq2 := round(s1);   // but back-conversion crashes
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  T: AThread;
begin
  T := AThread.Create(True);
  T.Start;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  raise Exception.Create('I can catch it'); 
end;

有没有办法从所有线程中捕获异常?异常可能由不同线程中的第三个库或 ActiveX 控件引发。

【问题讨论】:

  • madExcept 文档解释了如何执行此操作。你找到文档了吗?
  • 我将 TExceptEvent 误读为 TExceptType,所以我不明白该怎么做。感谢大卫提到这一点。

标签: delphi exception exception-handling ipc madexcept


【解决方案1】:

虽然我知道 MadExcept,但我没有个人经验,但在线程中捕获异常的通用方法是在线程的 Execute 方法中有一个 try...except 框架。在except...end 块中,您应该可以自己调用Form1.ApplicationEvent1Exception

【讨论】:

  • 不。不是这个。这里需要的是用询问者提供的处理程序替换 madExcept 未处理的异常对话框。易于操作且文档完善。
【解决方案2】:

我尝试了 madExcept,它能够捕获来自不同线程的异常。在进一步挖掘之后,我找到了一种在 madExcept 的帮助下静默捕获异常的方法。

procedure TForm1.HandleUncaughtException(const ExceptIntf: IMEException; var Handled: Boolean);
begin
  SendExceptionToAnotherProcess(ExceptIntf.ExceptMessage);
  Handled := True;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  madExcept.RegisterExceptionHandler(HandleUncaughtException, stTrySyncCallAlways, epMainPhase);
end;

【讨论】:

    猜你喜欢
    • 2011-05-20
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    相关资源
    最近更新 更多