views:

156

answers:

3

Hi again! 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  A: 

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.

Eugene Mayevski 'EldoS Corp
+6  A: 

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 else you must call ReleaseExceptionObject

Remko
+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 http://andy.jgknet.de/blog/?page_id=100. This unit will also show you how to use the code in the proper way.
mghie
A: 

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

MikeT