全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:935
推到 Plurk!
推到 Facebook!

How to handle exceptions in TThread objects

 
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-06-05 23:26:50 IP:61.64.xxx.xxx 未訂閱
How to handle exceptions in TThread objects
http://www.delphi32.com/info_facts/faq/faq_19.asp
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?
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 Unit ;
interface
uses
  Windows, Messages, SysUtils, Classes, 
  Graphics, Controls, Forms, Dialogs, StdCtrls;
type
  TForm  = class(TForm)
    Button : TButton;
    procedure Button Click(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
  Form : TForm ;
implementation
{$R *.DFM}
procedure TMyThread.DoHandleException;
begin
  // Cancel the mouse capture
  if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
  // 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 TForm .Button Click(Sender: TObject);
begin
  // Create an instance of the TMyThread
  with TMyThread.Create(True) do
  begin
    FreeOnTerminate := True;
    Resume; 
  end;
end;
end.     
系統時間:2024-06-29 17:09:23
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!