http://www.techques.com/question/1-3627743/Delphi-thread-exception-mechanism

i have a dilema on how threads work in delphi, and why at a moment when a thread should raise an exception,

the exception is not showed. bellow is the code with comments, maybe somebody cand explain to me how that thread,

or delphi, is managing access violations

//thread code

unit Unit2;

interface

uses
Classes,
Dialogs,
SysUtils,
StdCtrls; type
TTest = class(TThread)
private
protected
j: Integer;
procedure Execute; override;
procedure setNr;
public
aBtn: tbutton;
end; implementation { TTest } procedure TTest.Execute;
var
i : Integer;
a : TStringList;
begin
// make severals operations only for having something to do
j := ;
for i := to do
j := j + ;
for i := to do
j := j + ;
for i := to do
j := j + ;
for i := to do
j := j + ;
for i := to do
j := j + ;
for i := to do
j := j + ;
for i := to do
j := j + ;
for i := to do
j := j + ; Synchronize(setnr);
a[2] := 'dbwdbkbckbk'; //this should raise an AV!!!!!! end; procedure TTest.setNr;
begin
aBtn.Caption := IntToStr(j)
end; end.

project's code

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,
Unit2, StdCtrls; type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
public
nrthd:Integer;
acrit:TRTLCriticalSection;
procedure bla();
procedure bla1();
function bla2():boolean;
procedure onterm(Sender:TObject);
end; var
Form1: TForm1; implementation {$R *.dfm} procedure TForm1.bla;
begin
try
bla1;
except on e:Exception do
ShowMessage('bla '+e.Message);
end;
end; procedure TForm1.bla1;
begin
try
bla2
except on e:Exception do
ShowMessage('bla1 '+e.Message);
end;
end; function TForm1.bla2: boolean;
var ath:TTest;
begin
try
ath:=TTest.Create(true);
InterlockedIncrement(nrthd);
ath.FreeOnTerminate:=True;
ath.aBtn:=Button1;
ath.OnTerminate:=onterm;
ath.Resume;
except on e:Exception do
ShowMessage('bla2 '+e.Message);
end;
end; procedure TForm1.Button1Click(Sender: TObject); begin
//
try
bla;
while nrthd> do
Application.ProcessMessages;
except on e:Exception do
ShowMessage('Button1Click '+e.Message);
end;
ShowMessage('done with this');
end; procedure TForm1.FormCreate(Sender: TObject);
begin
nrthd:=;
end; procedure TForm1.onterm(Sender: TObject);
begin
InterlockedDecrement(nrthd)
end; end.

the purpose of this application is only to know where the access violation is catch, and how the code should be written.
i can not understand why in the line "a[2] := 'dbwdbkbckbk';" the AV is not raised.

thanks in advance and best regards!

hreading is one place where you should swallow exceptions.

The gist of handling Exceptions in threads is that if you want the exception to be shown to the end user,

you should capture it and pass it on to the main thread where it can safely be shown.

You'll find some examples in this EDN thread How to Handle exceptions in TThread Objects.

procedure TMyThread.DoHandleException;
begin
// Cancel the mouse capture
if GetCapture <> then SendMessage(GetCapture, WM_CANCELMODE, , );
// Now actually show the exception
if FException is Exception then
Application.ShowException(FException)
else
SysUtils.ShowException(FException, nil);
end; procedure TMyThread.Execute;
begin
FException := nil;
try
// raise an Exception
raise Exception.Create('I raised an exception');
except
HandleException;
end;
end; procedure TMyThread.HandleException;
begin
// This function is virtual so you can override it
// and add your own functionality.
FException := Exception(ExceptObject);
try
// Don't show EAbort messages
if not (FException is EAbort) then
Synchronize(DoHandleException);
finally
FException := nil;
end;
end;

In Delphi 2005 — and probably most other versions — if an exception escapes from the Execute method without being handled,

then it is caught by the function that called Execute and stored in the thread's FatalException property.

(Look in Classes.pasThreadProc.)

Nothing further is done with that exception until the thread is freed, at which point the exception is also freed.

It's your responsibility, therefore, to check that property and do something about it.

You can check it in the thread's OnTerminate handler.

If it's non-null, then the thread terminated due to an uncaught exception. So, for example:

procedure TForm1.onterm(Sender: TObject);
var
ex: TObject;
begin
Assert(Sender is TThread);
ex := TThread(Sender).FatalException;
if Assigned(ex) then begin
// Thread terminated due to an exception
if ex is Exception then
Application.ShowException(Exception(ex))
else
ShowMessage(ex.ClassName);
end else begin
// Thread terminated cleanly
end;
Dec(nrthd);
end;

We can also reraise FatalException.

Reraising seems not logical but if you have an central exception/error handler in your code and

and if you just want to include thread exceptions into that mechanisim, you can reraise on some rare situation :

procedure TForm1.onterm(Sender: TObject);
var
ex: Exception;
begin
Assert(Sender is TThread);
ex := Exception(TThread(Sender).FatalException);
if Assigned(ex) then
// Thread terminated due to an exception
raise ex;
Dec(nrthd);
end;

How to handle exceptions in TThread objects

By: Corbin Dunn

Abstract: This document describes how to properly handle and show an exception that happens in a thread.

Question: 
I have a TThread object which may raise an exception in the Execute procedure.

When an exception is raised, I want to be able to show that exception to the end user.

How do I go about doing this in the most efficient way?

Answer:
With a TThread object, if you don't catch an exception in the Execute procedure of a TThread,

you may get access violations.

The Delphi IDE may break fine on the exception, but often when the application is run outside of the IDE

you get an "Application error has occurred" exception and your application stops running.

If you don't care about showing the end user that an exception occurred,

you can simply wrap your Execute procedure with a try..finally block such as:

procedure TMyThread.Execute;
begin
try
// Do your thread stuff here
except // Eat all exceptions
end;
end;

Quite often, this isn't the best solution and you will want to show the message to the end user,

or allow your application to further process the message.

The easiest way to do this, is to add an Exception object to your TThread class,

and call the appropriate handler based on the type of exception.

Here is an example of how to do this.

The project consists of one form with a Button placed on it:

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 }
public
{ Public declarations }
end; TMyThread = class(TThread)
private
FException: Exception;
procedure DoHandleException;
protected
procedure Execute; override;
procedure HandleException; virtual;
public
end; var
Form1: TForm1; implementation {$R *.DFM} procedure TMyThread.DoHandleException;
begin
// Cancel the mouse capture
if GetCapture <> then SendMessage(GetCapture, WM_CANCELMODE, , );
// Now actually show the exception
if FException is Exception then
Application.ShowException(FException)
else
SysUtils.ShowException(FException, nil);
end; procedure TMyThread.Execute;
begin
FException := nil;
try
// raise an Exception
raise Exception.Create('I raised an exception');
except
HandleException;
end;
end; procedure TMyThread.HandleException;
begin
// This function is virtual so you can override it
// and add your own functionality.
FException := Exception(ExceptObject);
try
// Don't show EAbort messages
if not (FException is EAbort) then
Synchronize(DoHandleException);
finally
FException := nil;
end;
end; procedure TForm1.Button1Click(Sender: TObject);
begin
// Create an instance of the TMyThread
with TMyThread.Create(True) do
begin
FreeOnTerminate := True;
Resume;
end;
end; end.

vv

Delphi thread exception mechanism的更多相关文章

  1. Delphi之Exception获得错误信息(简单好理解)

    Delphi之Exception获得错误信息 相关资料: http://www.cnblogs.com/hackpig/archive/2010/02/15/1668547.html 实例代码: 1 ...

  2. Delphi:Exception输出堆栈信息

    起源: 用习惯了c#之Exception的StackTrace,在程序出异常crash时候能够以其定位出问题的模块及行号,用回Delphi 2009,发现没有这东西. 显然,在编译环境日新月异的今天, ...

  3. delphi:Exception EInvalidPointer in module Project1.exe

    在用delphi XE5编程时遇到如下问题: Exception EInvalidPointer in module Project1.exe at 00007595. Invalid pointer ...

  4. Delphi Thread.Queue与Synchronize的区别(差别: Synchronize是阻塞,Queue是非阻塞)

    前话:  其实大家要学会看源码, 我接下来要说的这些东东,与其等别人讲,还不如自己搞几个代码试一下,印象还深刻点 TThread.Queue和TThread.Synchronize的区别, 效果上:二 ...

  5. delphi.thread.同步

    注意:此文只是讲线程间的同步,其它同步不涉及. 线程同步是个好话题,因为写线程经常会遇到,所以就写写自己知道的东西. D里面,同步(特指线程同步)从线程的角度来分,有几种情况: 1:主线程与工作线程的 ...

  6. delphi.thread.线程循环执行体结构

    线程话题太大,又都是些坑,不知从哪方面讲起,所以,想一出是一出了. 不管怎样,我们从开始使用D,不管有没有用线程,其实它已经帮我们做了一个最完整的线程执行处理:Application.Run. 这行A ...

  7. Delphi之Exception获得错误信息

    1 unit Unit1; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Con ...

  8. Delphi Thread

    Thread给几点说明:1.MyThread的实例作为TForm1的成员变量2.不要使用Form1这个全局变量,线程中可要使用它的Handle,你可以在Form中创建MyThread的实例时把Hand ...

  9. Delphi DLL制作和加载 Static, Dynamic, Delayed 以及 Shared-Memory Manager

    一 Dll的制作一般分为以下几步:1 在一个DLL工程里写一个过程或函数2 写一个Exports关键字,在其下写过程的名称.不用写参数和调用后缀.二 参数传递1 参数类型最好与window C++的参 ...

随机推荐

  1. Spring3.0将全面支持REST

    Rod Johnson上个月底说,Spring 3.0全面支持REST风格的Web服务. "We're really seeing extensive interest and growth ...

  2. 使用Spring MVC统一异常处理实战

    1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...

  3. 字符串中符号的替换---replace的用法

    #include<iostream> #include<string> using namespace std; int main() { string s1 = " ...

  4. 【转】linux打包压缩命令

    转自:http://www.cnblogs.com/end/archive/2011/04/20/2022614.html tar命令 [root@linux ~]# tar [-cxtzjvfpPN ...

  5. HTML 学习进度备忘

    书签:”HTML 高级教程“及后面的内容尚未学习,另外跳过的内容有待跟进 __________________ 学习资源:W3School. 开始时间:2013.11.20 简述:此网址做为学习教程相 ...

  6. Page 16 Exercises 1.2.3 -------Introduction to Software Testing (Paul Ammann and Jeff Offutt)

    Below are four faulty programs. Each includes a test case that results in failure. Answer the follow ...

  7. 黑马程序员——经典C语言程序设计100例

    1.数字排列 2.奖金分配问题 3.已知条件求解整数 4.输入日期判断第几天 5.输入整数进行排序 6.用*号显示字母C的图案 7.显示特殊图案 8.打印九九口诀 9.输出国际象棋棋盘 10.打印楼梯 ...

  8. PHPCMS V9实现硬件地址MAC绑定访问技术实现

    目的:会员登录需要 用户名.密码.身份识别码(新增字段) 效果:  解决方法: 目前数据库中macaddress字段已经添加,修改了phpcms\modules\member\index.php 63 ...

  9. django部署到最后 主页上出现的坏请求解决办法

    ALLOWED_HOSTS = ['*'] 不然会出现400的坏请求 到此为止 环境总算配置完毕历时2天半重新熟悉了大量apache 和 linux下的命令

  10. 40 个顶级 jQuery 图片、内容滑块和幻灯片(转)

    在这个快速发展的网络世界中,我们使用图片.内容滑块和幻灯片来给网站实现良好.有吸引力的外观.你可以吸引浏览者借助图像滑块让网站更加具有活力.使用 JavaScript 可以轻松实现轻量级的图片和内容滑 ...