Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Funktionsaufruf einer DLL nach Timeout abbrechen (https://www.delphipraxis.net/133649-funktionsaufruf-einer-dll-nach-timeout-abbrechen.html)

Moony 6. Mai 2009 12:16


Funktionsaufruf einer DLL nach Timeout abbrechen
 
Hallo zusammen,

ich habe da eine blöde Situation:

Ich rufe innerhalb meiner Applikation eine Funktion aus einer beliebigen DLL auf. Normalerweise warte ich auf die Rückmeldung dieser DLL und werte den Rückgabewert der Funktion aus. Jetzt tritt der Fall ein, dass die DLL sich aufhängt und nicht mehr zurückkommen kann. Somit hängt auch meine Applikation. Das ist nicht vorteilhaft für den Benutzer, da er hier alles abschießen muss und ggf. das Sysstem neustarten muss.

Gibt es also eine Möglichkeit den Funktionsaufruf von meiner Applikation aus zu überwachen und nach einem definiertem Timeout hier abzubrechen und selbst eine Fehlerinterpretation durchzuführen. Die ehler auswerten sind ja kein Ding, aber der Abbruch nach einem Timeout. Ist sowas überhaupt möglich? Wenn ja, bitte erläutert wie.

Die DLL wird dynamisch geladen und die Funktion wird auch dynamisch mit GetProcAddress() geladen.

Danke & Gruß, Moony

Bernhard Geyer 6. Mai 2009 12:19

Re: Funktionsaufruf einer DLL nach Timeout abbrechen
 
Da wirst du einen Thread benötigen den du abschießen kannst.

sirius 6. Mai 2009 12:26

Re: Funktionsaufruf einer DLL nach Timeout abbrechen
 
Ist es evtl. gesünder einen zweiten Process zu starten, den man dann ggf. abschießt?

Fridolin Walther 6. Mai 2009 12:28

Re: Funktionsaufruf einer DLL nach Timeout abbrechen
 
Wie mein Vorredner schon sagte:
Funktion in einem Thread aufrufen, auf die Beendigung des Threads warten (MSDN-Library durchsuchenWaitForSingleObject - Timeout nach Wunsch setzen) und beim Eintreffen des Timeouts den Thread terminieren um die Funktion abzubrechen.

Zitat:

Zitat von sirius
Ist es evtl. gesünder einen zweiten Process zu starten, den man dann ggf. abschießt?

Am gesündesten wäre es die DLL zu fixen ;). Ansonsten kommt es drauf an was die DLL macht bzw. was den Fehler verursacht.

himitsu 6. Mai 2009 12:33

Re: Funktionsaufruf einer DLL nach Timeout abbrechen
 
na hoffentlich fängt man sich da keine Speicherlecks ein, wenn man den Thread einfach so abschießt...

was macht denn die Funktion, bzw. was soll sie machen und was sind "belibige" DLLs?

sirius 6. Mai 2009 12:59

Re: Funktionsaufruf einer DLL nach Timeout abbrechen
 
Zitat:

Zitat von himitsu
na hoffentlich fängt man sich da keine Speicherlecks ein, wenn man den Thread einfach so abschießt...

Deswegen würde ich eben hier auf Thread verzichten und lieber einen eigenständigen Process nehmen. Da weis ich, das Windows aufräumt.
Und ja, schön ist das allemal nicht, aber über die DLL kann man hier nicht weiter urteilen.

Moony 6. Mai 2009 13:13

Re: Funktionsaufruf einer DLL nach Timeout abbrechen
 
Erst mal danke für die vielen Vorschläge!

Ich werde mir die Funktion WaitForSingleObject mal genauer anschauen.
Was die Funktion der DLL bzw. beliebige DLL's betrifft, habe ich keine Information. Es gibt eine definierte Schnittstelle in meiner Applikation, über die andere DLL's angebunden werden können und was auch immer ausführen. Was sie machen habe ich keine Ahnung und auch keinen Einfluss drauf. Das soll mir auch egal sein. Ich will nur sicherstellen, falls eine DLL unsauber programmiert wurde - auf die ich keinen Einfluss habe - will ich zumindest sicherstellen, dass meine Applikation nicht auch im Nirvana hängt.

himitsu 6. Mai 2009 14:09

Re: Funktionsaufruf einer DLL nach Timeout abbrechen
 
falls deine Schnittstelle nur Daten verschickt, aber ihr der Rückgabewert (nach 'ner Weile) egal ist,
dann könnte man es ja so einrichten, daß die "Nachrichten" je in eimem Thread nur weggegeben werden und die Anwendung garnicht oder nicht lange auf das Beenden der Bearbeitung der DLL-Funktion wartet.


Praoktisch so wie bei MSDN-Library durchsuchenSendMessage und MSDN-Library durchsuchenPostMessage Postmessage gibt die Nachricht nur ab und kehrt sofort zurück und SendMessage wartet solange bis diese Nachricht auch bearbeitet wurde.

Moony 6. Mai 2009 14:44

Re: Funktionsaufruf einer DLL nach Timeout abbrechen
 
Die Antwort der DLL ist mir natürlich nicht egal. Ich warte ja bis jetzt auf eine Antwort und je nachdem wie sie ausgefallen ist werte ich das aus und arbeite weiter in meiner Applikation. Wenn aber jedoch die Funktion im Nirvana landet, dann muss ich reagieren können, damit meine Applikation nicht auch im Nirvana steht.

Bezüglich der Funktion WaitForSingleObject kann in soweit schon Ausagen treffen, dass das nicht funktionieren kann. Denn die Funktion überwacht ein Handle das ich ihr übergebe. Ich habe aber lediglich ein Handle der DLL nicht aber der Funktion die ich aufgerufen habe. Von dieser habe ich eine Adresse und diese kann ich nicht an die WaitForSingleObject übergeben.

Demnach besteht wohl nur noch die Möglichkeit von 2 Threads: Timer-Thread und der Thread der Funktion aufruft.

Wenn ich eine Antwort bekommen habe oder aber das TimeOut abläuft, werden anschließend beide Threads beendet und ich arbeite weiter mit meiner Applikation je Rückgabewert.

Fridolin Walther 6. Mai 2009 15:31

Re: Funktionsaufruf einer DLL nach Timeout abbrechen
 
Du solltest lesen was ich geschrieben hab ...

Du startest einen Thread, der die DLL Funktion aufruft. Natürlich hast Du von dem Thread das Handle - wird ja von MSDN-Library durchsuchenCreateThread zurückgeliefert ;). Das Thread Handle kannst Du dann für MSDN-Library durchsuchenWaitForSingleObject benutzen. Das ganze würde in etwa so aussehen:
Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  Windows;

type
  TParameters = record
      Parameter1 : dword;
      Parameter2 : dword;
      Parameter3 : dword;
      Result : dword;
  end;
  PParameters = ^TParameters;

function SometimesDoesntReturn(parameter1, parameter2, parameter3 : dword) : dword;
begin
  result := 0;
  case random(2) of
    0 : sleep(INFINITE);
    1 : result := Parameter1 + Parameter2 + Parameter3;
  end;
end;

function CallWrapper(Parameters : PParameters) : dword; stdcall;
begin
  Parameters^.Result := SometimesDoesntReturn(Parameters^.Parameter1, Parameters^.Parameter2, Parameters^.Parameter3);
end;

var
  Parameters : TParameters;
  ThreadID, ThreadHandle : dword;
  i : integer;
begin
  Randomize;

  for i := 0 to 19 do
    begin
      Parameters.Parameter1 := random(100000);
      Parameters.Parameter2 := random(100000);
      Parameters.Parameter3 := random(100000);
      ThreadHandle := CreateThread(nil, 0, @CallWrapper, @Parameters, 0, ThreadID);
      case WaitForSingleObject(ThreadHandle, 1000) of
        WAIT_OBJECT_0 : writeln('Aufruf erfolgreich -> Result: ', Parameters.Result);
        WAIT_TIMEOUT : writeln('Aufruf haengt -> TerminateThread: ', TerminateThread(ThreadHandle, 0));
      end;
      CloseHandle(ThreadHandle);
    end;
  readln;
end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:22 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz