Jag hittade precis ett riktigt svårupptäckt fel som gjorde att minnet på webservern tog slut. Det var ett fel som uppstod ibland så det gick inte riktigt att återskapa felet och det var som att leta efter en nål i en höstack. Äntligen hittade jag det :)
Men hur gör man för att undvika att loopar blir för stora på ett bra sätt?
Om man tex har en loop som ser ut så här:
For X = 0 To Total
...
Next
Så här skulle man kunna göra för att underlätta felsökning och undvika stora loopar:
For X = 0 To Total
...
If X > 10000 Then
Throw New Exception("Loop exception....")
End if
Next
Skulle ni gjort så som ovan eller skulle ni försökt göra det på ett annat sätt? Sen undrar jag i vilka fall man bör lägga in felhantering i större loopar? Själv har jag aldrig sett någon felhantering på detta sätt i loopar men det kanske inte är så dumt? Det enda jag sett några gånger under de år jag jobbat som programmerare är tex en if-sats som kontrollerar räknaren och därefter gör en exit for eller liknande för att undvika evighetsloppar eller större loopar.
Varför rekommenderar du att man inte har felhantering i looparna? Skulle du lägga felhantering utanför loopen eller skulle du skipa det helt?
Jag har inte så stor erfarenhter av tex test-driven-utveckling men jag ser fördelar med det. Jag har dock svårt att se att man har den tillräckliga tid som krävs för att skriva vattentäta unit-tester. Jag skulle nog säga att ett bra komplement till unit-testerna skulle vara någon form av felhantering i loopar.
Performance monitoring är bra men den ger mer en övergripande bild över läget. Det är svårt att hitta ett specifikt fel i koden med hjälp av det.
Om du är orolig för loopar när datamängden kan vara väldigt stor får du sätta upp test som simulerar det, har du problem med koden kan du använda profilerverktyg såsom ants profiler för att se vart koden tar lång tid att exekvera. Skulle lagt felhanteringen utanför loopen
Byt till Rails där test driven development är en fest!
Nej, men ärligt talat... Iterationer kan kräva mycket av servern. Beroende på vad du vill göra/gör kanske det kan vara idé att t.ex. låta databasen sortera och välja ut data. (Om det nu är data från en databas du arbetar med.) Db-servrar är ju skapade och optimerade för den typen av arbete.
Eftersom jag inte är en hejare på ASP så får du lite pseudo-kod ! :)
FEL:
hämta alla objekt
för varje objekt
om objektet(färg) == gul
visa objektet
slut
RÄTT
hämta alla objekt(färg == gul)
för varje objekt
visa objektet
slut
Detta förslag fick jag på ett annat forum och det är nog det vettigaste. På detta sätt slipper man gå in i en stor loop i fall det skulle vara fel. Jag får dock uppfattningen att många inte är för detta :) Inga ja-sägare?
If Total > 10000 Then Throw New Exception("Loop exception....")
For X = 0 To Total
...
Next
Men hur gör man för att undvika att loopar blir för stora på ett bra sätt?
Jag har svårt att se det här som ett generellt problem.
I de fall där det beror på att man själv gjort nåt fel (typ skrivit en SQL-fråga som returnerar tusenfalt fler rader än man tänkt sig) är det bara en bugg, och det enda sättet man kan stampa ut buggar på är kodgranskning och tester. Att slänga in lite Debug.Assert, ArgumentExceptions och liknande i koden är förstås aldrig fel. Men gör det på rätt ställe, du bränner bara en massa processorcykler på att göra kollen inuti loopen. Effektivare:
If Total > 10000 Then
Throw New Exception("Loop exception....")
End if
For X = 0 To Total
...
Next
red. Så hinner du förstås skriva samma sak själv innan jag postar. Tacksamt :OO ;)
Nåväl, vidare i sak:
Sen finns de fall där det beror på användardata som kommer in, typ "antal poster på sidan". I de fallen är det bara helt vanlig indatavalidering som gäller, kanske kombinerat med en tyst korrigering, som i freguz exempel.
Men som sagt, jag har svårt att se det här som ett generellt problem :) Visst sätter mina program att loopa amok med jämna mellanrum, men det är inte konstigare än att mina if-satser får fel i sina villkor etc. Det bästa sättet att motverka det på tycker jag dock är spårutskrifter kombinerat med en debugger så man ser vad som händer.
Jag har svårt att se att stora loopar (ej evighetsloopar) skulle vara ett direkt problem med minneshanteringen. Jag ser inte heller själva loopkoden som en nödvändig bugg eftersom felet i så fall ligger i datamängden som inkommer i koden innan loopen.
Så länge man ej skrivit ett extremt resurskrävande program där man allokerar minne inuti loopen så är stora loopar mer ett prestandaproblem än minnesproblem. Man bör nämligen aldrig t.ex. deklarera nya variabler inuti en loop såvida det inte är absolut nödvändigt utan deklarera dessa innan loopen och gärna återanvända variablerna i varje loop iteration.
Nu har jag visserligen aldrig grävt ner mig ordentligt i minneshanteringen i .net och C# speciellt utan arbetar mest i C++ och dess minneshantering där man måste vara observant på minnesanvändning för att inte introducera minnesläckor.
261 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e