Infinite Loop

Tags:    delphi

Hvad er fremgangsmåde når du skal lave en applikation som skal stå og arbejde konstant, 24/7 ?

Hvis man laver denne kode her (nedenfor) så bruger programmet 100% CPU. Det jeg leder efter er en løsning hvor et program står konstakt og checker efter ændring i systemet, og når der sker nogle udfører noget kode. Men hvis programmet bruger 100% bare på at stå og glo så er man nødt til at have en dedikeret server til netop dette program hvilket er lidt overkill!

Fold kodeboks ind/udKode 


// Thomas Bresson



7 svar postet i denne tråd vises herunder
0 indlæg har modtaget i alt 0 karma
Sorter efter stemmer Sorter efter dato
Indsæt et Application.ProcessMessages kald efter hver gang løkken kaldes, dvs. sidst i

EDIT: Så ikke du havde det... Sorry. Prøv med et Sleep(10) kald. Det vil få din process til at sove i 10 millisekunder, hvilket burde være nok.

lykken.
MH.

The-Freak

Livet er for kort til at kede sig.


[Redigeret d. 30/08-05 16:03:05 af The-Freak]




Efter min opfattelse en fundamentalt set forkert måde at lave din applikationen på (!). Hvorfor? Applicationen stopper ganske vidst midlertidigt så den kan behandle indkommende messages, men forbruger potentiel stadigvæk CPU cycles.

En bedre løsning er. Lav en klasse der arver fra Thread og i denne klasses execute metode benyttes Win32 API kald til WaitForSingleObject eller WaitForMultipleObjects. Nu bliver dit program NOTIFICERET når der er ændringer i systemet eksempelvis ændringer i registeringsdatabasen eller filsystemet. Blot for en god ordens skyld - du kan også sætte en timer argument til WaitForSingleObject.

Kort sagt: Søg en gang på Google efter WaitForSingleObject og Delphi så er der nok nogle eksempler du kan bruge.

Held og lykke med projektet ;-).




Iler lige med en stump kode jeg åbenbart skrev engang for 5 år siden til en anden, der havde et lignende spm.

Først oprettes et notifikationsobjekt (button1), dernæst kaldes WaitForSingleObject (button2). Normalt ville jeg anbring det - som tidligere nævnt - i en særskilt tråd. Prøv koden, start programmet og dernæst tilføj en eller anden fil på c-drevet.

procedure TForm1.Button1Click(Sender: TObject);
begin
{notifications objektet oprettes}
NotificationHandle := FindFirstChangeNotification
('C:\\'
, false
, FILE_NOTIFY_CHANGE_FILE_NAME);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
Waiting : boolean;
dwresult: DWORD;
begin
Waiting := true;
application.processMessages;
while Waiting do
begin
dwResult := WaitForSingleObject(Notificationhandle, INFINITE);
if (dwResult = WAIT_OBJECT_0) then
begin
if application.messagebox('Monitoring?'
,'Continue'
, MB_ICONQUESTION or MB_YESNO)
= IDYES then
begin
FindNextChangeNotification(NotificationHandle)
end
else
Waiting := false;

end
end;
FindCloseChangeNotification(Notificationhandle);
end;



Ja du har fuldstændig ret. Jeg skulle jo starte ét sted for at forklare folk hvordan situationen ser ud. Notification objekt hmmm.. spændende.

Jeg må dog indrømme at når vi snakker threading, arvning og klasser så står jeg sgu' af. Det er lige indviklet nok må jeg indrømme, men jeg vil forsøge at se på det objekt engang, samt WaitForSingleObject og/eller WaitForMultipleObjects.

PS: Jeg kan åbenbart ikke give dig point Jørgen, da websitet siger, der ikke er nogen, der har svaret ?!




Helt Okay - Jeg har også kun angivet mit svar som en kommentar.



Hm. jeg kan se det fungerer ret godt, og det virker umiddelbart meget godt. Men man har som jeg kan se ingen mulighed for at stoppe programmet med mindre, du på én eller anden måde indvolvere noget threading kode som du snakker om.

Men jeg synes threading virker meget advanceret. Kan du give nogle tips, kode, links eller noget, der kan hjælpe mig.

Jeg er ikke tilhænger af at smide et sleeper ind i programmer, der brugeren mulighed for kun at stoppe programmet hvis programmet har fx fundet en fil, og så kun i x antal sekunder herefter. Sæt nu der ikke kommer en fil osv.

Jeg har rodet med threading før, og så vidt jeg kan se så er folk mere til at bruge Windows' API i stedet for Delphi's TThread objekt, men tja, så strækker min erfaring sig ikke så meget mere end blot at prøve at copy/paste lidt rundt og forsøge at lave ADOQueries inde i en thread som jeg ikke engang kan huske hvordan jeg fik lavet dengang, hehe




Nu er det efterhånden et stykke tid siden jeg skrev programmer i Delphi og pt. har jeg det da heller ikke installeret. Men nogle ideer kan jeg da nok give:

Først og fremmest så skal du nok bruge WaitForMultipleObjects eftersom det giver dig mulighed for flere objekter. Der skal lidt flere parameter til WaitForMultipleObjects, nemlig:

1) antal handles i array bestående af handles

2) pointer til array af handles.

3) boolsk flag som angiver om alle objekter skal være signal eller ej.

4) Timeout fx. INFINITE


I din array of handles kan være et EventObjekt - se WIN api32 CreateEvent(). Når du har behov for at afslutte programmet (via en knap i din brugergrænseflade) så ændre du blot tilstand på dette objekt og WaitForMultipleObjects ophører med at vente. I din kode er du så nødt til at checke et eller andet flag som angiver det er event objektet og ikke din filenotification som er den udløsende årsag.





t