【问题标题】:How to catch an exception generated in a Thread to be able to manipulate it如何捕获线程中生成的异常以便能够对其进行操作
【发布时间】:2017-11-23 17:54:56
【问题描述】:

我的应用程序中有一个处理生成的异常的过程。事实证明,如果在 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;

【问题讨论】:

  • 在主线程中引发异常。这就是你想要的吗?
  • 我希望所有从“TThreadDSR”生成的异常都可以被“DM.HandleExceptions”捕获,这样我就可以处理错误消息了。

标签: exception delphi-7


【解决方案1】:

异常不会跨越线程边界。如果未捕获的异常逃脱了TThread.Synchronize() 调用的过程,Synchronize() 将捕获异常并在工作线程的上下文中重新引发它。如果Execute() 随后没有捕获到异常,线程将终止并将异常分配给TThread.FatalException 属性。

您可以使用TThread.OnTerminate 事件(在主线程的上下文中调用)将FatalException 传递给您的HandleExceptions() 过程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-11
    • 1970-01-01
    相关资源
    最近更新 更多