Seite 1 von 3
60% CPU-Auslastung trotz WaitWindowEvent()?
Verfasst: 04.08.2018 11:11
von Delle
Hallo,
ich verwende diesen Code an einer bestimmten Stelle, er wartet meist eine zufällige Anzahl Minuten und prüft aber gleichzeitig ob der User evtl. abbricht:
Code: Alles auswählen
Repeat
EventID = WaitWindowEvent()
If EventID = #PB_Event_CloseWindow:End:EndIf
If EventID=#PB_Event_Gadget And EventGadget()=#Suche
SetGadgetText(#Suche, "Suche starten")
SetGadgetText(#Browser,"about:blank")
Break(3)
EndIf
Until (pausi + StartTime)<ElapsedMilliseconds()
Wieso verursacht das aber trotz WaitWindowEvent() fast 60% CPU-Auslastung?!
Danke!
Re: 60% CPU-Auslastung trotz WaitWindowEvent()?
Verfasst: 04.08.2018 11:27
von #NULL
Leider ist nicht ersichtlicht was das Break 3 macht, da zu viel code fehlt. Aber auf jedenfall könnte dein SetGadgetText(#Suche.. erneut ein Event für genau dieses Gadget auslösen, womit du eine Art Endlosschleife erzeugst. Du solltest auch den EventType prüfen damit die Events die von SetGadgetText() verursacht werden nicht wieder ein SetGadgetText() auslösen.
Re: 60% CPU-Auslastung trotz WaitWindowEvent()?
Verfasst: 04.08.2018 11:49
von Delle
Sieht grob so aus:
Code: Alles auswählen
Repeat
EventID = WaitWindowEvent(50)
If EventID=#PB_Event_Gadget And EventGadget()=#Suche
If GetGadgetText(#Suche)="Suche starten"
SetGadgetText(#Suche, "Suche anhalten")
EndIf
Repeat
; ABLAUF START (Schleife)
pausi.l = Random(1000*60*3,1000*60*1)
StartTime.q = ElapsedMilliseconds()
Repeat
EventID = WaitWindowEvent()
If EventID = #PB_Event_CloseWindow:End:EndIf
If EventID=#PB_Event_Gadget And EventGadget()=#Suche
SetGadgetText(#Suche, "Suche starten")
SetGadgetText(#Browser,"about:blank")
Break(3)
EndIf
Until (pausi + StartTime)<ElapsedMilliseconds()
; ABLAUF WEITER
ForEver
EndIf
;While WindowEvent():Wend
Until EventID = #PB_Event_CloseWindow
Läuft der WindowEvent in der Hauptschleife wohl auch noch!?
Re: 60% CPU-Auslastung trotz WaitWindowEvent()?
Verfasst: 04.08.2018 12:07
von Delle
Lassen wir mal die Interaktionen durch den User ganz weg, also weder Fensterschließen, noch irgendwelche Gadgets.
Das Programm soll beim Start sofort loslaufen, Abbruch durch Taskmanager.
Code: Alles auswählen
Repeat
If DatabaseQuery(#DB, "SELECT * FROM tabelle")
While NextDatabaseRow(#DB)
SetGadgetText(#Browser, GetDatabaseString(#DB, DatabaseColumnIndex(#DB, "url")))
; Warten bis Webseite in #Browser fertig geladen
; Diverse Aktionen durchführen
; Pause für 5 Minuten
Wend
Forever
Bei Pause könnte ich einfach Delay(1000*60*50) nehmen, dann ist die CPU zumindest auf 0 aber das Programm ist als "inaktiv" markiert und gibt keine Rückmeldung (sieht halt aus als ob es "hängt").
Was/wo müssten da für WindowsEvents oben in den Code rein damit er nicht wieder die CPU durchknallt?
Re: 60% CPU-Auslastung trotz WaitWindowEvent()?
Verfasst: 04.08.2018 13:02
von #NULL
Ist #Suche ein Button? Wie gesagt, auch auf EventType filtern
Code: Alles auswählen
If EventID=#PB_Event_Gadget And EventGadget()=#Suche And EventType() = #PB_EventType_LeftClick
SetGadgetText(#Suche, "Suche starten")
<edit>
Du hast da oben zwei Event-Schleifen drin. Man kann sowas machen, will man aber lieber nicht.
Re: 60% CPU-Auslastung trotz WaitWindowEvent()?
Verfasst: 04.08.2018 16:04
von silbersurfer
Ohne jetzt genauers zu durchleuchten,
das SetGadgetText sollte nicht in der Wartescheife stehen, da dardurch auch ein Event ausgelöst wird.
was
#NULL dir schon gesagt hatte
erneut ein Event für genau dieses Gadget auslösen, womit du eine Art Endlosschleife erzeugst
So ist es besser
Code: Alles auswählen
Repeat
If DatabaseQuery(#DB, "SELECT * FROM tabelle")
SetGadgetText(#Browser, GetDatabaseString(#DB, DatabaseColumnIndex(#DB, "url")))
While NextDatabaseRow(#DB)
EventID = WaitWindowEvent()
; Warten bis Webseite in #Browser fertig geladen
; Diverse Aktionen durchführen
; Pause für 5 Minuten
Wend
Forever
Re: 60% CPU-Auslastung trotz WaitWindowEvent()?
Verfasst: 04.08.2018 16:12
von Delle
@silbersurfer:
Da setzt Du ja die URL ins Gadget, bevor überhaupt die DB-Schleife anfängt zu laufen
Also mir würde wiegesagt auch eine Version OHNE jegliche Usereingaben via Gadget reichen, HAUPTSACHE die CPU läuft low.
Aktuell eben bei 60-70% und der Laptoplüfter dreht fast durch...
Re: 60% CPU-Auslastung trotz WaitWindowEvent()?
Verfasst: 04.08.2018 17:50
von mk-soft
Zeit intensive Bearbeitungen immer in einem Thread auslagern...
Um aus einen Thread die GUI zu aktualisieren, habe ich ja noch das Module ThreadToGUI.
Re: 60% CPU-Auslastung trotz WaitWindowEvent()?
Verfasst: 04.08.2018 18:49
von Delle
mk-soft hat geschrieben:Zeit intensive Bearbeitungen immer in einem Thread auslagern...
Hatte ich ja ursprünglich gemacht, allerdings schmierte da ja immer das Programm ab. Threads und Gadgets halt...
mk-soft hat geschrieben:Um aus einen Thread die GUI zu aktualisieren, habe ich ja noch das Module ThreadToGUI.
Bläht den Code unnötig auf und schickt irgendwelche Daten Ping-Pong... der Thread muss ja auch wieder wissen wann z.B. das WebGadget fertig mit laden ist.
Re: 60% CPU-Auslastung trotz WaitWindowEvent()?
Verfasst: 04.08.2018 23:01
von mk-soft
Das problem ist, wann das Webgadget wirklich fertig ist mit den Laden der Webseite...
Nur mal schnell zusammengebastelt...
Code: Alles auswählen
;-TOP
CompilerIf #PB_Compiler_Thread = 0
CompilerError "Compiler-Option Threadsafe aktivieren!"
CompilerEndIf
; Constant
Enumeration Window
#Main
EndEnumeration
Enumeration Menu
#Menu
EndEnumeration
Enumeration MenuItems
#MenuStartThread
#MenuExitApplication
EndEnumeration
Enumeration Gadgets
#List
#Browser
EndEnumeration
Enumeration Statusbar
#Status
EndEnumeration
; -----------------------------------------------------------------------------
Enumeration CustomEvent #PB_Event_FirstCustomValue
#MyEventLoadURL
EndEnumeration
Structure udtWork
ThreadID.i
Exit.i
; Daten
List URL.s()
EndStructure
Structure udtSendData
Status.i
Semaphore.i
URL.s
EndStructure
Procedure thWork(*data.udtWork)
Protected SendData.udtSendData
With *data
SendData\Semaphore = CreateSemaphore()
ForEach \URL()
SendData\Status = 0
SendData\URL = \URL()
PostEvent(#MyEventLoadURL, 0, 0, 0, @SendData)
WaitSemaphore(SendData\Semaphore)
;TODO
Delay(5000)
Next
FreeSemaphore(SendData\Semaphore)
EndWith
EndProcedure
Global WorkData.udtWork
Procedure StartThread()
With WorkData
If IsThread(\ThreadID)
ProcedureReturn 0
EndIf
AddElement(\URL()) : \URL() = "http://www.t-online.de"
AddElement(\URL()) : \URL() = "about:blank"
AddElement(\URL()) : \URL() = "http://www.heise.de"
AddElement(\URL()) : \URL() = "http://www.chip.de"
AddElement(\URL()) : \URL() = "http://www.purebasic.com"
\ThreadID = CreateThread(@thWork(), WorkData)
ProcedureReturn 1
EndWith
EndProcedure
; -----------------------------------------------------------------------------
; Global Variable
Global ExitApplication
; Functions
Procedure UpdateWindow()
Protected x, y, dx, dy, menu, status
menu = MenuHeight()
If IsStatusBar(#Status)
status = StatusBarHeight(#Status)
Else
status = 0
EndIf
x = 0
y = 0
dx = WindowWidth(#Main)
dy = WindowHeight(#Main) - menu - status
ResizeGadget(#List, x, y, dx, dy)
EndProcedure
; Main
Procedure Main()
Protected event, style, *MyEventData.udtSendData
style = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
dx = 800
dy = 600
If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, dx, dy, "Main", style)
; Enable Fullscreen
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Protected NewCollectionBehaviour
NewCollectionBehaviour = CocoaMessage(0, WindowID(#Main), "collectionBehavior") | $80
CocoaMessage(0, WindowID(#Main), "setCollectionBehavior:", NewCollectionBehaviour)
CompilerEndIf
; Menu
CreateMenu(#Menu, WindowID(#Main))
MenuTitle("Ablage")
MenuItem(#MenuStartThread, "Start Thread...")
MenuBar()
MenuItem(#MenuExitApplication, "Be&enden")
; Gadgets
ListViewGadget(#List, 0, 0, dx, dy)
WebGadget(#Browser, 0, 0, 0, 0, "about:blank")
; Statusbar
CreateStatusBar(#Status, WindowID(#Main))
AddStatusBarField(#PB_Ignore)
UpdateWindow()
; Main Loop
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_Menu
Select EventMenu()
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Case #PB_Menu_About
Case #PB_Menu_Preferences
Case #PB_Menu_Quit
ExitApplication = #True
CompilerEndIf
Case #MenuExitApplication
ExitApplication = #True
Case #MenuStartThread
StartThread()
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #List
Case #Browser
Select EventType()
Case #PB_EventType_DownloadStart
AddGadgetItem(#List, -1, "Download Start URL - " + GetGadgetText(#Browser))
Case #PB_EventType_DownloadEnd
AddGadgetItem(#List, -1, "Download End URL - " + GetGadgetText(#Browser))
If *MyEventData
*MyEventData\Status + 1
If *MyEventData\Status = 1
SignalSemaphore(*MyEventData\Semaphore)
EndIf
EndIf
EndSelect
EndSelect
Case #PB_Event_SizeWindow
Select EventWindow()
Case #Main
UpdateWindow()
EndSelect
Case #PB_Event_CloseWindow
Select EventWindow()
Case #Main
ExitApplication = #True
EndSelect
Case #MyEventLoadURL
*MyEventData = EventData()
AddGadgetItem(#List, -1, "Thread Request URL - " + *MyEventData\URL)
SetGadgetText(#Browser, *MyEventData\URL)
EndSelect
Until ExitApplication
EndIf
EndProcedure : Main()
End