Delphi32.com - Home!
| Home/News | Downloads | Forums | D32 Magazine | Resources | Info and Facts |  
 
 How to handle exceptions in TThread objects


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.

     


  << Previous Faq     Complete List     Next Faq >>  



 
 Hits/month  2,500,000+ 
 Downloads
 (Since May 2000)
 7,393,709 
 Total Files  6,023 
 Forum msgs  7,670 
 Articles/FAQs  70+/900+ 
Kylix
Tips n Tricks
FAQs
Knowledge Base
Bug Listings
Articles
Books
Newsgroups
Links
Submissions
Testimonials
Advertising
Contact Us
About Us
Search Amazon:
Top Selling Software at Amazon

| Home/News | Downloads | Forums | Resources | Info and Facts | Testimonials |
  Site Search:
 


Comments/Problems: Webmaster@delphi32.com
Copyright © 1998-2006, Delphi32.com. All rights reserved.
Terms of Use