| 订阅 | 在线投稿
分享
 
 
 

捕捉来自 Thread 的异常

来源:互联网网民  宽屏版  评论
2008-06-01 01:27:37

Thread我们进行应用和设计时不可缺少的利器,然而它却不是轻易就可以把握的。作为一个不可视系统组件,它封装在TThread类中,由于一个子线程可以与主线程同时运行,因此,来自子Thread的异常在主程序里未必能捕捉到,这样,来自子线程的异常就会导致Application的错误甚至是崩溃,也可能造成主程序都结束了,某个Thread还因等待同步对象的信号还在那儿自己运行着。所以,对于有必要进行异常控制的Thread就必须进行异常处理,这个异常处理块最好独立于主程序的异常处理模块。我们都知晓对通常异常的捕捉都用一个try..finally块来处理,而对来Thread

的异常也不例外:

procedure TMyThread.Execute;

begin

try

// 在安全区应该做的工作

except

// 处理所有的异常

end;

end;

通常,这样的处理可以正常的工作,但却不是恰当的解决方法。我们希望不仅把异常信息传递给用户,而且要求在不影响Thread继续工作的前提下,由Application

或系统单元(致命异常)来进一步处理异常。要做这样处理,首先,我们在自己的 Thread 类里定义一个异常对象,由这个对象承载各种要处理的异常类实例。其次,建立响应异常的同步事件。对EAbort消息加以抑制,对来自程序本身的异常由Application处理,对系统级异常,一般交与操作系统来完成。以下是一个简单的异常捕捉应用框架。

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes,

Graphics, Controls, Forms, Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Button1: TButton;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

Procedure RunThread;

public

{ Public declarations }

end;

TBaseThread = class(TThread)

private

FException: Exception;

procedure DoHandleException;

protected

procedure Execute; override;

//父类函数为虚,在子类再重载其而处理具体事宜

procedure HandleException; virtual;

public

end;

TMyThread = class(TBaseThread)

private

...

protected

procedure Execu override;

procedure HandleException; override;

...

public

...

end;

var

Form1: TForm1;

implementation

{$R *.DFM}

procedure TBaseThread.DoHandleException;

begin

// 关闭当前主窗体对鼠标的响应

if GetCapture $#@60;$#@62; 0 then SendMessage(GetCapture, WM_CANCELMODE,

0, 0);

// 判定异常的范围并做相应处理

if FException is Exception then

Application.ShowException(FException)

else

SysUtils.ShowException(FException, nil);

...

end;

procedure TBaseThread.Execute;

begin

FException := nil;

try

...

//处理一些事情

except

//假如发生了异常

HandleException;

end;

end;

procedure TBaseThread.HandleException;

begin

//得到当前异常对象

FException := Exception(ExceptObject);

try

//避免因 EAbort 消息使程序推出

if not (FException is EAbort) then

Synchronize(DoHandleException);

finally

FException := nil;

end;

end;

procedure TMyThread.Execute;

begin

...

end;

procedure TMyThread.HandleException;

begin

...

end;

procedure TForm1.RunThread;

begin

//为 TMyThread 类创建实例

with TMyThread.Create(True) do

begin

FreeOnTerminate := True;

Resume;

end;

end;

...

 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
Thread我们进行应用和设计时不可缺少的利器,然而它却不是轻易就可以把握的。作为一个不可视系统组件,它封装在TThread类中,由于一个子线程可以与主线程同时运行,因此,来自子Thread的异常在主程序里未必能捕捉到,这样,来自子线程的异常就会导致Application的错误甚至是崩溃,也可能造成主程序都结束了,某个Thread还因等待同步对象的信号还在那儿自己运行着。所以,对于有必要进行异常控制的Thread就必须进行异常处理,这个异常处理块最好独立于主程序的异常处理模块。我们都知晓对通常异常的捕捉都用一个try..finally块来处理,而对来Thread 的异常也不例外: procedure TMyThread.Execute; begin try // 在安全区应该做的工作 except // 处理所有的异常 end; end;   通常,这样的处理可以正常的工作,但却不是恰当的解决方法。我们希望不仅把异常信息传递给用户,而且要求在不影响Thread继续工作的前提下,由Application 或系统单元(致命异常)来进一步处理异常。要做这样处理,首先,我们在自己的 Thread 类里定义一个异常对象,由这个对象承载各种要处理的异常类实例。其次,建立响应异常的同步事件。对EAbort消息加以抑制,对来自程序本身的异常由Application处理,对系统级异常,一般交与操作系统来完成。以下是一个简单的异常捕捉应用框架。 unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type   TForm1 = class(TForm)   Button1: TButton;   procedure Button1Click(Sender: TObject); private   { Private declarations }   Procedure RunThread; public   { Public declarations } end; TBaseThread = class(TThread) private   FException: Exception;   procedure DoHandleException;   protected   procedure Execute; override;   //父类函数为虚,在子类再重载其而处理具体事宜   procedure HandleException; virtual; public end; TMyThread = class(TBaseThread) private   ...   protected   procedure Execu override;   procedure HandleException; override;   ... public   ... end; var Form1: TForm1; implementation {$R *.DFM} procedure TBaseThread.DoHandleException; begin // 关闭当前主窗体对鼠标的响应 if GetCapture $#@60;$#@62; 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0); // 判定异常的范围并做相应处理 if FException is Exception then   Application.ShowException(FException) else   SysUtils.ShowException(FException, nil);   ... end; procedure TBaseThread.Execute; begin   FException := nil; try ... //处理一些事情 except //假如发生了异常   HandleException; end; end; procedure TBaseThread.HandleException; begin //得到当前异常对象   FException := Exception(ExceptObject); try //避免因 EAbort 消息使程序推出   if not (FException is EAbort) then     Synchronize(DoHandleException); finally   FException := nil; end; end; procedure TMyThread.Execute; begin ... end; procedure TMyThread.HandleException; begin ... end; procedure TForm1.RunThread; begin //为 TMyThread 类创建实例 with TMyThread.Create(True) do begin FreeOnTerminate := True; Resume; end; end; ...
󰈣󰈤
 
 
 
>>返回首页<<
 
 热帖排行
 
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
©2005- 王朝网络 版权所有