11

I have another question! Please look at this example:

// There is a class with some method:
type
  TMyClass = class
  public
    procedure Proc1;
  end;

  // There is a some thread class:
  TMyThread = class(TThread)
  protected
    procedure Execute; override;
  end;

procedure TMyClass.Proc1;
begin
  // this method is just calling another thread:
  with TMyThread.Create(True) do
  begin
    FreeOnTerminate := True;
    Resume;
  end;
  // + there are some more actions
end;

procedure TMyThread.Execute;
begin
  // in this example this thread just throws exception:
  raise Exception.Create('Some exception');
end;

All what i want - is to get raised exception in the TMyClass.Proc1 and throw it up like this:

var
  myObject: TMyClass;
begin
  myObject := TMyClass.Create;
  try
    myObject.Proc1; // launch and watch what happenings
  except
    on E: Exception do
      WriteErrorLog(E.Message);
  end;
  FreeAndNil(myObject);
end;

Please tell me how can i make something like this? Many Thanks!

oh! one more thing - im coding on Delphi 5 so i have'nt "FatalException" property of TThread or something about..

1
  • 3
    You need to accept an answer or if no answer is complete enough for you indicate that eg by comment
    – Remko
    Commented Sep 29, 2010 at 11:27

4 Answers 4

22

You can use AcquireExceptionObject():

AcquireExceptionObject returns a pointer to the current exception object and prevents the exception object from being deallocated when the current exception handler exits.

Then you can send the pointer to another thread and if you raise it there it will be freed for you, otherwise you must call ReleaseExceptionObject() to free it.

5
  • 5
    +1 for AcquireExceptionObject(). Since it isn't available in Delphi 5 you should copy the implementation for Delphi 5 from AsyncCalls.pas, which can be downloaded from andy.jgknet.de/blog/?page_id=100. This unit will also show you how to use the code in the proper way.
    – mghie
    Commented Sep 27, 2010 at 9:06
  • Is AcquireExceptionObject thread safe? At least I'm getting strange results when using it in multiple threads i.e. blocking occurs?
    – iPath ツ
    Commented Mar 16, 2013 at 0:05
  • The exception is an instance of an object so I assume it's thread safe (supported by the fact that docs don't mention it)
    – Remko
    Commented Mar 16, 2013 at 19:11
  • AWESOME ANSWER!
    – Javid
    Commented Jan 27, 2017 at 0:22
  • +1. For C++Builder users, note that AcquireExceptionObject() may be unreliable under the new Clang-based compiler. See RSP-18031. Commented May 3, 2017 at 15:29
2

In brief, you can't do this the way you want.

You need to clone the exception object, pass the copy to your other thread (eg. using Synchronize method or using other synchronization technique) and raise that exception object there.

0

Your best trapping the exception in the execute loop on the thread and writing the message property and classname to a private string field. This can then be made public using a property with critical sections in the getters and setters, ensuring access is threadsafe. Now all you have to do is pass into the thread a process to handle the exception and call it with a synchronise. I will post some example code when I get to my computer, as I,m using my iPhone at the moment

-1

I do this sort of thing natively in my multi-threaded framework (http://www.csinnovations.com/framework_overview.htm).

1
  • Actually, I just noticed you are still using Delphi 5 so it won't be of much help.
    – Misha
    Commented Feb 20, 2011 at 9:50

Not the answer you're looking for? Browse other questions tagged or ask your own question.