[Delphi] Stukje code een time-out geven

Pagina: 1
Acties:
  • 100 views sinds 30-01-2008
  • Reageer

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Is het mogelijk in Delphi dat je een bepaalde stukje code een time-out geeft.
Ik lees namelijk uit een DLL een string uit (is een functie in die DLL met een ShortString). Maar dit wil nog wel es heel lang duren, en soms krijg ik gewoon niks uit die DLL.
Nu wil ik dat het uitlezen maar bijvoorbeeld 10 seconden mag duren, als ik dan nog niks heb van die functie (uit die DLL) heb moet hij de boel cancellen.

Is hier een mooie/nette manier voor? Is een thread een idee?

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 16-09 18:04

Creepy

Tactical Espionage Splatterer

eehh.. tread starten die dat ding uitleest. En dan in je mainthread wachten totdat je thread is beeindigt OF de 10 secs is verstreken.
Is de 10 secs verstreken dan de thread afknallen en doorgaan.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Met een thread dus. Ga het proberen.

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

ik denk niet dat het zonder thread mogelijk is.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Oke, ik heb alles in een thread gegooit. Werkt perfect.

Tevens een timer gemaakt die bij de start van de thread wordt ingeschakeld en bij de OnTerminate event van de thread wordt uitgeschakeld. Werkt goed.

Bij de OnTimer event van de timer heb ik Thread.Terminate gezet. Dit voert hij wel uit, maar de thread wordt niet direct gestopt. Waarom niet?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Omdat de thread blokkeert [op het inlezen van de dll(?)], nadat de thread niet meer geblokkeert is, ontvangt hij de timer event en stopt.

edit:

De thread zal dus - net als eerst de main-thread deed - gewoon blokkeren. Je hebt daar natuurlijk in de main-thread geen last van...

De thread stopt na het uitvoeren van de code in Execute. Dus als jouw Execute er zoiets uitziet...
[code]procedure TMyThread.Execute;
begin
DoeIets;
end;[/code]
...en in DoeIets zit geen oneindige lus dan zal de thread na verloop van tijd stoppen, een timer om de thread te stoppen is dan niet nodig.

Meestal ziet de Execute er als volgt uit:
[code]procedure TMyThread.Execute;
begin
while not Terminated do
DoeIets;
end;[/code]

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Maar het is zo dat ik in die Execute procedure alles doe van die thread, behalve het aanmaken van objecten. Dat doe ik binnen de Create procedure.

Volgens mij is het voor mij niet echt mogelijk om die "do while terminated" toe te voegen. Of zie ik dat verkeerd?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Dat maakt niet uit; ik bedoelde te zeggen dat je geen timer nodig hebt, omdat de thread toch wel eindigt.

Verder zal de thread geen messages ontvangen zolang hij niet idle wordt. Dus als de thread continue draait [hoe zeg je dit normaal :?] zal hij de timer event niet krijgen.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op donderdag 22 november 2001 22:03 schreef DiFool het volgende:
Dat maakt niet uit; ik bedoelde te zeggen dat je geen timer nodig hebt, omdat de thread toch wel eindigt.

Verder zal de thread geen messages ontvangen zolang hij niet idle wordt. Dus als de thread continue draait [hoe zeg je dit normaal :?] zal hij de timer event niet krijgen.
Idd, daar was ik dus ook achter gekomen. De thread stop niet als ik via de main-thread (goede benaming?) een Terminate event stuur naar die thread omdat hij nog bezig is met zijn Execute procedure.

Wat is dat wel een oplossing om dit te realiseren?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Als je TThread.Terminate aanroept wordt alleen de var FTerminated op True gezet.

Als je dan een lus in je thread hebt kijk je af en toe of Terminated True is dus
code:
1
2
while not Terminated do
  DoeIets;

Als je geen lus hebt zou je zoiets kunnen doen
code:
1
2
3
4
5
6
7
8
9
10
procedure TMyThread.Execute;
begin
  DoeIets1;
  if Terminated then Exit;

  DoeIets2; 
  if Terminated then Exit;

  ..
  DoeIetsN;

Maar dat is IMHO lelijke code. Maar mijn punt is eigenlijk dat als je geen lus hebt, de thread toch wel eindigt en je geen noodstop nodig hebt... [Maar ik weet niet hoe jouw code eruit ziet natuurlijk]

Verder maak ik op uit jouw opmerkingen dat de code die je in de thread uitvoert, alleen lang duurt omdat die tijdelijk blockt. In deze toestand kan de thread niet op messages etc reageren dus heeft het dan ook geen zin om een message naar de thread te sturen of TThread.Terminate aan te roepen.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op donderdag 22 november 2001 22:41 schreef DiFool het volgende:
Verder maak ik op uit jouw opmerkingen dat de code die je in de thread uitvoert, alleen lang duurt omdat die tijdelijk blockt. In deze toestand kan de thread niet op messages etc reageren dus heeft het dan ook geen zin om een message naar de thread te sturen of TThread.Terminate aan te roepen.
Klopt wel.

Wat ik in die Execute doe is 2 tal functies aaroepen van een DLL. Maar aangezien die functies in die DLL wel es heel lang kunnen duren (omdat ze iets van internet ophalen bijvoorbeeld) of soms helemaal geen return waarde geven (die boel binnen de DLL blijft hangen), wil ik dit kunnen terminaten.
Kan de main-thread niet gewoon die hele Thread trashen. Dus een harde stop zeg maar? Of is dit niet een goede manier?

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Misschien is het wel beter dat ik het probleem binnen de DLL probeer op te lossen. Ik weet het niet.

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Je zou TerminateThread kunnen proberen, maar of dat nou een aanrader is...

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op donderdag 22 november 2001 23:00 schreef DiFool het volgende:
Je zou TerminateThread kunnen proberen, maar of dat nou een aanrader is...
Ik probeer het probleem eerst binnen de DLL op te lossen. Daar wordt namelijk via een TIdHTTP component data van internet gehaald. Helaas heeft versie 8 van Indy geen time-out functies, 9 beta wel.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 08-09 08:43

Bergen

Spellingscontroleur

Ja, waarom duurt het dan zo lang voor de DLL het teruggeeft? Heeft die het zo druk dan?

  • jopiek
  • Registratie: September 2000
  • Laatst online: 21-08 19:56

jopiek

Tja... 'ns ff denken.

Hoi Jelmer, ik weet niet of je vaak met threads geproggred hebt, maar je moet exact goed omgaan met critische secties etc. om geen problemen te krijgen (Matering Delphi 6 heeft een mooi stukje erover)...

Je kunt uiteraard gewoon timen en dan virtueel de threads bijhouden... Je laat de reeele thread gewoon uitriedelen en de virtuele thread (voor admin doeleinden dus) zet je getimed op non-actief... Lijkt me het beste...

Cogito Ergo Credo


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op donderdag 22 november 2001 23:50 schreef jopiek het volgende:
Hoi Jelmer, ik weet niet of je vaak met threads geproggred hebt, maar je moet exact goed omgaan met critische secties etc. om geen problemen te krijgen (Matering Delphi 6 heeft een mooi stukje erover)...
Ik weet het. Heb al die voorbeelden en die teksten erbij door genomen. Wordt allemaal goed en duidelijk uitgelegd.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op donderdag 22 november 2001 23:46 schreef GerbenW het volgende:
Ja, waarom duurt het dan zo lang voor de DLL het teruggeeft? Heeft die het zo druk dan?
Hij haalt iets van internet (HTTP) met een Indy HTTP client component. Maar het wil nog wel es gebeuren dat ie blijft hangen ofzo. In Indy 8 zit dus geen time-out optie.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Lasoul
  • Registratie: November 2001
  • Laatst online: 11:03
Hi,

Is het gebruik voor WaitForSingleObject een idee? Hierbij
kun je de timeout gebruiken... je moet er wat omheen
programmeren maar het zou volgens mij moeten lukken (heb
nu ff geen Delphi bij de hand, maar heb het gebruikt
voor het aanspreken van een devicedriver met timeout)

Groet,

Patrick

Verwijderd

WaitForSingleObject - de naam zegt het al - dan wacht je totdat een object in een bepaalde toestand komt, je kunt dit wachten oneindig laten duren of afbreken na een bepaalde tijd.

In dit geval moet er helemaal niet gewacht worden. Dus WaitForSingleObject is hier niet van toepassing.

Maar het klopt wel dat WaitForSingleObject etc. vaak worden gebruikt in threads.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik heb even gezocht, er zijn meer met dit probleem.
http://groups.google.com/groups?q=IdHTTP+time-out

Als oplossing wordt gegeven: upgraden naar Indy 9.0B

Hier heeft de HTTP component een time-out functie. Als ik dit gebruik wordt het probleem binnen de DLL opgelost. Is dus een oplossing. :)

"The shell stopped unexpectedly and Explorer.exe was restarted."

Pagina: 1