2010-09-27 7 views
8

J'ai une autre question! S'il vous plaît consulter cet exemple:Comment passer une exception d'un thread à un autre thread (appelant) dans 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; 

Tout ce que je veux - est de faire exception soulevée dans le TMyClass.Proc1 et le jeter comme ça:

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; 

s'il vous plaît me dire comment puis-je faire quelque chose comme ça? Merci beaucoup!

oh! une chose de plus - im codant sur Delphi 5 donc je n'ai pas la propriété "FatalException" de TThread ou quelque chose à propos de ..

+2

Vous devez accepter une réponse ou si aucune réponse n'est suffisamment complète pour que vous indiquiez que par exemple – Remko

Répondre

2

En bref, vous ne pouvez pas faire cela comme vous le souhaitez.

Vous devez cloner l'objet d'exception, transmettre la copie à votre autre thread (par exemple en utilisant la méthode Synchronize ou en utilisant une autre technique de synchronisation) et y lever cet objet d'exception.

17

Vous pouvez utiliser AcquireExceptionObject():

AcquireExceptionObject renvoie un pointeur sur l'objet d'exception actuelle et empêche l'objet d'exception d'être désallouée lorsque la sortie du gestionnaire d'exception en cours.

Ensuite, vous pouvez envoyer le pointeur à un autre thread et si vous soulevez là il sera libéré pour vous, sinon vous devez appeler ReleaseExceptionObject() pour le libérer.

+5

+1 pour 'AcquireExceptionObject()'. Comme il n'est pas disponible dans Delphi 5, vous devez copier l'implémentation de Delphi 5 depuis AsyncCalls.pas, qui peut être téléchargée depuis http://andy.jgknet.de/blog/?page_id=100. Cette unité vous montrera également comment utiliser le code correctement. – mghie

+0

Le thread AcquireExceptionObject est-il sécurisé? Au moins, je reçois des résultats étranges lorsque je l'utilise dans plusieurs threads, c'est-à-dire que le blocage se produit? –

+0

L'exception est une instance d'un objet, donc je suppose qu'il est thread safe (supporté par le fait que les docs ne le mentionnent pas) – Remko

0

Votre meilleur interception de l'exception dans la boucle d'exécution du thread et l'écriture de la propriété de message et du nom de classe dans un champ de chaîne privée. Cela peut ensuite être rendu public en utilisant une propriété avec des sections critiques dans les getters et les setters, en s'assurant que l'accès est threadsafe. Maintenant tout ce que vous avez à faire est de passer dans le thread un processus pour gérer l'exception et l'appeler avec une synchronisation. Je vais poster un exemple de code quand j'arriverai à mon ordinateur, comme je l'utilise actuellement avec mon iPhone

-1

Je fais ce genre de chose nativement dans mon framework multi-thread (http://www.csinnovations.com /framework_overview.htm).

+0

En fait, je viens de remarquer que vous utilisez encore Delphi 5 donc ça ne sera pas d'une grande aide. – Misha

Questions connexes