2010-09-27 22 views
8

¡Tengo otra pregunta! Por favor mira este ejemplo:Cómo pasar la excepción de un hilo a otro (el que llama) el hilo en Delphi?

// 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; 

Todo lo que quiero - es conseguir excepción planteada en la TMyClass.Proc1 y tirarlo así:

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; 

Por favor, dígame cómo puedo hacer algo ¿Me gusta esto? Muchas gracias!

oh! una cosa más: estoy codificando en Delphi 5 así que no tengo la propiedad "FatalException" de TThread o algo así ...

+2

Necesita aceptar una respuesta o si no hay respuesta es suficiente para indicar que, por ejemplo, mediante el comentario – Remko

Respuesta

2

En resumen, no puedes hacer esto de la manera que quieras.

Necesita clonar el objeto de excepción, pasar la copia a su otro hilo (por ejemplo, utilizando el método Synchronize o utilizando otra técnica de sincronización) y elevar ese objeto de excepción allí.

17

Puede utilizar AcquireExceptionObject():

AcquireExceptionObject devuelve un puntero al objeto excepción actual y evita que el objeto de excepción de ser desasignado al salir del gestor de excepciones actuales.

A continuación, puede enviar el puntero a otro hilo y si se eleva allí que serán liberados para usted, de lo contrario debe llamar ReleaseExceptionObject() para liberarla.

+5

+1 para 'AcquireExceptionObject()'. Como no está disponible en Delphi 5, debe copiar la implementación de Delphi 5 desde AsyncCalls.pas, que se puede descargar desde http://andy.jgknet.de/blog/?page_id=100. Esta unidad también le mostrará cómo usar el código de la manera adecuada. – mghie

+0

¿Es seguro el subproceso AdquireExceptionObject? Al menos estoy obteniendo resultados extraños al usarlo en varios hilos, es decir, ¿se produce el bloqueo? –

+0

La excepción es una instancia de un objeto, así que supongo que es seguro para subprocesos (respaldado por el hecho de que los documentos no lo mencionan) – Remko

0

Lo mejor es atrapar la excepción en el bucle de ejecución en el hilo y escribir la propiedad del mensaje y el nombre de clase en un campo de cadena privada. Esto se puede hacer público usando una propiedad con secciones críticas en getters y setters, asegurando que el acceso sea seguro para los hilos. Ahora todo lo que tiene que hacer es pasar a la secuencia un proceso para manejar la excepción y llamarla con una sincronización. Voy a publicar un código de ejemplo cuando llegue a mi computadora, ya que estoy usando mi iPhone en el momento

-1

Hago este tipo de cosas de forma nativa en mi marco multi-hilo (http://www.csinnovations.com /framework_overview.htm).

+0

En realidad, me acabo de dar cuenta de que todavía está usando Delphi 5 por lo que no será de mucha ayuda. – Misha

Cuestiones relacionadas