如何让Application.OnException能捕获子线程的异常?

FlashDance 2014-12-01 02:15:07
procedure TFormMain.AppException(Sender: TObject; E: Exception);
begin
Application.MessageBox(PChar(E.Message), PChar(E.ClassName));
end;


procedure TFormMain.FormCreate(Sender: TObject);
begin
Application.OnException := AppException;
end;


希望能在Application.OnException中统一处理所有异常
如果子线程中出现异常,如何能让Application.OnException捕获?
...全文
230 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
pathletboy 2014-12-02
  • 打赏
  • 举报
回复
1、不要把异常抛来抛去,某个类里产生的异常尽量在该类中处理掉,除非实在无法处理再抛给外部,当然这种情况下程序基本是停摆了。 2、异常处理开销很大,尽量少用,如果你用的某些库使用了异常机制,那就尽量在你自己的模块里把异常处理了。 3、你这种所谓统一处理异常的想法是不合理的,这样会导致代码耦合度降低。 当然如果你执意这么干,可以访问下面这个字段 Exception(pr.ExceptionInformation[1]) 这个字段存放的就是Exception对象,但我还是建议你重新架构下你的程序,因为你这么写很不合理。
FlashDance 2014-12-02
  • 打赏
  • 举报
回复
引用 6 楼 pathletboy 的回复:
1、不要把异常抛来抛去,某个类里产生的异常尽量在该类中处理掉,除非实在无法处理再抛给外部,当然这种情况下程序基本是停摆了。 2、异常处理开销很大,尽量少用,如果你用的某些库使用了异常机制,那就尽量在你自己的模块里把异常处理了。 3、你这种所谓统一处理异常的想法是不合理的,这样会导致代码耦合度降低。 当然如果你执意这么干,可以访问下面这个字段 Exception(pr.ExceptionInformation[1]) 这个字段存放的就是Exception对象,但我还是建议你重新架构下你的程序,因为你这么写很不合理。
讲的非常详细,非常感谢
FlashDance 2014-12-01
  • 打赏
  • 举报
回复
引用 4 楼 pathletboy 的回复:
[quote=引用 3 楼 FlashDance 的回复:] 或者在子线程中将这个异常类:E.Message,E.ClassName抛给主线程呢?
try...except啊,捕获了你想怎么传递给主线程都可以。[/quote] 在FormCreate时,就交给ExceptionHandler统一处理异常了 但在pr里没有发现pr.Message,pr.ClassName获取异常类名等信息啊
pathletboy 2014-12-01
  • 打赏
  • 举报
回复
引用 3 楼 FlashDance 的回复:
或者在子线程中将这个异常类:E.Message,E.ClassName抛给主线程呢?
try...except啊,捕获了你想怎么传递给主线程都可以。
FlashDance 2014-12-01
  • 打赏
  • 举报
回复
或者在子线程中将这个异常类:E.Message,E.ClassName抛给主线程呢?
FlashDance 2014-12-01
  • 打赏
  • 举报
回复
能否得到异常的类名:E.Message,E.ClassName 能否用if (E is EIdSocketError) or (E is EInvalidOperation) then来处理异常呢?

procedure TFormMain.AppException(Sender: TObject; E: Exception);
begin
  if (E is EIdSocketError) or (E is EInvalidOperation) then
  begin
    //*******************
  end
  else if E.Message = '更新文件失败' then
  begin
    //************
  end
  else
    Application.MessageBox(PChar(E.Message), PChar(E.ClassName));
end;
pathletboy 2014-12-01
  • 打赏
  • 举报
回复
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function AddVectoredExceptionHandler(FirstHandler: ULONG; VectorHandlerFunc: Pointer): THandle; stdcall; external 'Kernel32.dll';


function ExceptionHandler(const exce: TExceptionPointers): LongInt; stdcall;
const
  EXCEPTION_CONTINUE_SEARCH = 0;
  EXCEPTION_EXECUTE_HANDLER = 1;
  EXCEPTION_CONTINUE_EXECUTION = -1;
var
  pr: Windows.PExceptionRecord;
begin
  pr := exce.ExceptionRecord;
  ShowMessage(Format('发生异常%.8x 异常地址%.8x',
    [pr.ExceptionCode, Cardinal(pr.ExceptionAddress)]));
  if pr.ExceptionCode = $80000003 then
  begin
    exce.ContextRecord.ContextFlags := CONTEXT_CONTROL;
    exce.ContextRecord.Eip := exce.ContextRecord.Eip  + 1;
    Result := EXCEPTION_CONTINUE_EXECUTION;
    Exit;
  end;

  Result := EXCEPTION_CONTINUE_SEARCH;
end;


procedure MyThread();
begin
  asm
    int 3
  end;
end;

procedure TForm1.btn1Click(Sender: TObject);
var
  lp: Cardinal;
begin
  CreateThread(nil, 0, @MyThread, nil, 0, lp);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  AddVectoredExceptionHandler(0, @ExceptionHandler);
end;

end.
要自己处理seh,例子在上,处理int3异常,并恢复运行。

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧