2010-09-27 16 views
8

Mam kolejne pytanie! Proszę spojrzeć na ten przykład:Jak przekazać wyjątek z wątku do wątku (dzwoniącego) w 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; 

Wszystko czego chcę - jest, aby podniesiony wyjątek w TMyClass.Proc1 i rzucać go tak:

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; 

Proszę mi powiedzieć w jaki sposób mogę zrobić coś lubię to? Wielkie dzięki!

o! jeszcze jedno - im kodowanie na Delphi 5, więc nie mam "FatalException" właściwość TThread lub coś o ..

+2

Musisz zaakceptować odpowiedź lub jeśli odpowiedź nie jest wystarczająco kompletna, aby wskazać, że np. Przez komentarz – Remko

Odpowiedz

2

W skrócie, nie można zrobić tak, jak chcesz.

Należy sklonować obiekt wyjątku, przekazać go do innego wątku (np. Za pomocą metody Synchronizuj lub używając innej techniki synchronizacji) i podnieść tam obiekt wyjątku.

17

Można użyć AcquireExceptionObject():

AcquireExceptionObject zwraca wskaźnik do bieżącego obiektu wyjątku i zapobiega obiekt wyjątku przed dealokowane gdy prąd wyjścia obsługi wyjątku.

Następnie można wysłać wskaźnik do innego wątku, a jeśli go nie podniesie zostanie uwolniony dla ciebie, w przeciwnym razie trzeba by go nazwać ReleaseExceptionObject() uwolnić.

+5

+1 dla 'AcquireExceptionObject()'. Ponieważ nie jest dostępny w Delphi 5, powinieneś skopiować implementację Delphi 5 z AsyncCalls.pas, którą można pobrać z http://andy.jgknet.de/blog/?page_id=100. Ta jednostka pokaże Ci również, w jaki sposób poprawnie korzystać z kodu. – mghie

+0

Czy wątek AcquireExceptionObject jest bezpieczny? Przynajmniej otrzymuję dziwne wyniki, gdy używam go w wielu wątkach, tj. Występuje blokowanie? –

+0

Wyjątkiem jest instancja obiektu, więc zakładam, że jest bezpieczna dla wątków (obsługiwana przez fakt, że dokumenty o niej nie wspominają). – Remko

0

Twoje najlepsze zalepienie wyjątku w pętli wykonywania w wątku i zapisanie właściwości komunikatu i nazwy klasy w prywatnym polu ciągu. Można to następnie upublicznić za pomocą właściwości o krytycznych sekcjach w programach pobierających i ustawiających, zapewniając dostęp do wątków bezpiecznie. Teraz wystarczy, że przekażesz wątkowi proces obsługujący wyjątek i wywołasz go zsynchronizowaniem. Wezmę przykładowy kod, gdy dotrę do mojego komputera, ponieważ ja, m używając mojego iPhone'a w tej chwili,

-1

Robię coś takiego natywnie w mojej wielowątkowej strukturze (http://www.csinnovations.com /framework_overview.htm).

+0

Właściwie to zauważyłem, że nadal używasz Delphi 5, więc nie będzie to zbyt pomocne. – Misha

Powiązane problemy