31. juli 2001 - 12:05Der er
11 kommentarer og 1 løsning
VB program tager alle ressourcer
Jeg har et VB - program som kører på en Windows PC og med mellemrum (p.t. 20 sekunder) kommunikerer med en COM-port og henter data fra et eksternt apparat. Kommunikationen består både i at afsende og modtage data.
Der er desværre det problem, at programmet, som ikke er særlig stort, stjæler alle ressourcer på PC\'en (uanset Windows - version) og ender med at \"fryse\" PC\'en.
Er der nogen, som kan give mig et hint om, hvor jeg eventuelt kan sætte ind? Jeg har ikke selv programmeret det, men har kildekoden og kan trække på hjælp fra programmører. Jeg kan desværre ikke lægge kildekoden ud, da den er ejet af mit firma, men alle forslag er velkomne.
Der kører ikke andre programmer, f.eks. virusscannere, på PC\'en.
Vi bruger DoEvents i programmet. Problemet er, at vi skal sende et tegn for at få data tilbage, og det er tilsyneladende når vi venter på svar, at problemet opstår. Vi sender med 20 sekunders interval. Vi kan have 2 versioner kørende, hvor nr.1 bruger 100% af ressourcerne og nr.2 ingenting, selv om nr.2 fungerer og indlæser data, som den skal. Pludselig kan de 2 programmer begynde at dele ressourcerne med 50% til hver, og de kan også bytte plads!
Hvordan kommunikerer du med COM-porten, bruger du MsComm eller noget andet? Det du skriver ligner meget, at der bliver brugt \'busy wait\' når der ventes på data fra COM-porten.
Hvordan venter i præcist på input? Bruger I OnComm eventet til at få at vide at \'noget\' er kommet, eller spørger I i en løkke på CommEvent indtil \'noget\' er kommet.
Hvis I bruger OnComm: Hvad foretager I jer i programmet, indtil OnComm eventet faktisk indtræffer?
bemærk at blnDataSent er en global Boolean variabel og at den eksterne enhed ikke automatisk laver en comEvReceive men skal trigges med et \"$\" og et \"&\" tegn
Private Sub objMSComm_OnComm() Select Case objMSComm.CommEvent \' ..... \'Diverse fejlhåndtering \' ..... Case comEvReceive Call RecieveData
Case ComEvSend blnDataSent = True \' .....
End Select
End Sub
Hvert 20 sec bliver en anden sub kaldt der skulle trigge den eksterne enhed til at sende den ser ud som følger.
\'Send a datasend Call SendData(\"&\") Do While blnDataSent = False DoEvents ***************************************** Loop blnDataSent = False
\'Wait for the package to be recieved Do While blnFrameRecieved = False DoEvents Loop
blnFrameRecieved = False
If blnFrameAccepted = True Then
If blnEndOfFrames = True Then Exit Sub
\'Send a data erase to delete the accepted package and continue with the loop Call SendData(\">\") Do While blnDataSent = False DoEvents Loop
blnDataSent = False
strRecieveData = \"\"
Else
Call SendData(\"<\") Do While blnDataSent = False DoEvents Loop blnDataSent = False
strRecieveData = \"\" End If
End Sub
Endvidere er der en sub til at læse data på event \"comEvReceive\" den er i princippet irelevant. Jeg har markeret det sted i programmet hvor den looper med ************ Efter min bedste overbevisning burde Doevents overgive kontrollen til systemet så den ikke æder alle ressourcer.
Jeg vil lige bemærke at jeg er rimelig nybegynder med VB programmering så i må bærer over med diverse kindergardenkoder :o)
Programmet lider ganske som jeg antog under \'busy wait\'. Prøv at omstrukturere til noget i retning af følgende:
Dim Receivebuf as string
Private Sub objMSComm_OnComm() Select Case objMSComm.CommEvent \' ..... \'Diverse fejlhåndtering, herunder noget fornuftigt hvis afsendelsen af \"$&\" \' går galt \' ..... Case comEvReceive \' Hent alt hvad der er kommet, og tilføj til Receivebuf Receivebuf = Receivebuf & objMSComm.Input
\' Find ud af, om et komplet telegram er modtaget, hvis ja - behandl det. \' Hvis nej - gør ingenting, da resten kommer om lidt
Case ComEvSend \' ..... unødvendigt at gøre noget
End Select
End Sub
Private Sub Start() \' Tøm modtagebufferen, som forberedelse til næste telegram Receivebuf = \"\"
\' Start afsendelsen af \"$&\". objMSComm.Output = \"$&\"
\' Hele resten sker i OnComm End Sub
Som det ses, er der ingen løkker og ingen DoEvents. Den fundamentale grund til den oprindelige misere er, at jeres forståelse af DoEvents er ufuldstændig. DoEvents er et kald til systemet, som vil få systemet til at behandle alt hvad der måtte have ophobet sig af events. Når dette er sket, returneres øjeblikkelig til programmet! (og dette er årsagen til løkken).
Det er ret sjældent man har brug for DoEvents, men et eksempel er: Man har et program, der laver nogle udregninger, der tager rigtig lang tid. Undervejs ønskes det at præsentere på en form, hvor langt man er kommet. Hvis man bare sætter tallet ind i formen og regner videre, vil tallet ikke blive synligt for brugeren. Hvis tallet skal synliggøres, skal programmet kalde DoEvents for at få behandlet skærmopdaterings-eventet.
Bemærk, at i skitsen ovenfor er der IKKE taget højde for, at jeres apparat måske kan finde på at sende et ufuldstændigt telegram. Dette må håndteres med noget passende timeout-overvågning.
Det er ikke lige til at gætte, men her er et par ting, I kunne undersøge:
- Er der trafik på den serielle ledning, mens problemet er synligt? Med lidt held, kan dette ses på lysdioder på det eksterne apparat, ellers kan jeg anbefale en seriel linie-tester, sådan en med en lysdiode for hvert signal. Et oscilloskop kan også bruges.
- Holder problemet op, hvis I trækker stikket ud?
- Kan det tænkes, at der er en situation, hvor MsComm genererer en masse fejl-events, som I ikke behandler, og de derfor bliver gentaget uendeligt? Prøv evt at logge alle MsComm events i en fil for at se, hvad der kommer.
Det er sådan lidt revl og krat, håber I kan bruge noget af det.
Det kan meget vel være en af de muligheder, du foreslår. Men vi har i alle tilfælde fået et mere stabilt program ved at bruge dine forslag, og vi vil arbejde videre med det, du foreslår. Især den med de mange fejl-events lyder interessant, selv om der er en ret omfattende fejlbehandling i programmet. Det eksterne apparat har også nogle \"særheder\", som vi skal tage højde for - og der dukker hele tiden nogle overraskelser op. Men tusind tak for dine meget kvalificerede svar, som har hjulpet os meget.
Mvh
Tommy Madsen
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.