Ich möchte im Systray eine Anwendung welche mir alle x Minuten eine Systemabfrage startet.
(Im konkreten Fall: -Wieviel Speicherplatz ist noch auf Laufwerk C:, bzw. Sende einen Ping und warte auf Rückmeldung)
Immer mal wieder lese ich im Board dazu Themen über Prozessorauslastung und Timerschleifen, Threads, etc..
Daher wieder einmal meine Frage wie man so etwas am besten 'richtig' programmiert:
- Wie baut man denn grundsätzliche eine Schleife für so eine Anwendung auf?
- Kennt jemand ein 'gutes' Grundgerüst für eine solche Anwendung?
(Mir geht es nur um den Beispiel-Code für die 'Zeitschleife' (Alle z.B: 5 Minuten eine Abfrage; dazwischen 'ruhen' und die anderen Programme (Prozessor,etc..) so wenig als möglich 'stören/belasten'.)
Danke
Kaltstart
Zeitliche Abfragen im Systray; Suche 'guten/optimalen' Code
Was du suchst nennt sich SetTimer. Einfach hier im Forum suchen.
Einfach via Timer alle x - Minuten eine Abfrage starten und mit einem Systray - Icon koppeln. So sollte das gehen, die Abfrage musst du noch selbst machen:
Gruß, Alex
Code: Alles auswählen
; ------------------------------------------------------------------------------------
; Easy Timer
; Einfacher leicht erweiterbarer Timer
; PB 4.3 +
; Alexander Aigner
; V 1.0
; ------------------------------------------------------------------------------------
; ------------------------------------------------------------------------------------
; Internes Zeugs
; ------------------------------------------------------------------------------------
; ------------------------------------------------------------------------------------
; HighRes - Timer
; ------------------------------------------------------------------------------------
EnableExplicit
Prototype HR_Time()
Structure _HR_Internal
StartTime.q
Res.d
EndStructure
Define _HR._HR_Internal
Global GetTimeMS.HR_Time
Procedure _HR_InitTime()
Shared _HR._HR_Internal
Protected Frequency.q
With _HR
If Not QueryPerformanceFrequency_(@Frequency)
ProcedureReturn #False
Else
QueryPerformanceCounter_(@\StartTime)
\Res = 1000/Frequency
ProcedureReturn #True
EndIf
EndWith
EndProcedure
Procedure _HR_Get()
Shared _HR._HR_Internal
Protected currentTime.q
With _HR
QueryPerformanceCounter_(@currentTime)
ProcedureReturn (currentTime-\StartTime)*\Res
EndWith
EndProcedure
Procedure _HR_oldPC_or_Linux()
ProcedureReturn ElapsedMilliseconds()
EndProcedure
; Initialisierung des High-Res Timers
CompilerIf #PB_Compiler_OS<>#PB_OS_Windows
GetTimeMS = @_HR_oldPC_or_Linux()
CompilerElse
If _HR_InitTime()
GetTimeMS = @_HR_Get()
Else
GetTimeMS = @_HR_oldPC_or_Linux()
EndIf
CompilerEndIf
; ------------------------------------------------------------------------------------
; Eigentlicher Timer
; ------------------------------------------------------------------------------------
Prototype ET_Procedure(Event, UserData)
Enumeration ; Sollte klar sein ...
#ET_Call
#ET_Pause
#ET_Resume
#ET_Free
EndEnumeration
Structure ET_Data
*CB.ET_Procedure
UserData.i
Delay.i
CBEvent.i
CBEventStop.i
CBEventPause.i
EndStructure
Procedure _ET_Thread(*ET.ET_Data)
Protected cTime, wTime
With *ET
wTime = \Delay
Repeat
cTime = GetTimeMS()
While wTime>GetTimeMS()-cTime
Delay(1)
Wend
If \CBEvent ; Nur 1. If-Abfrage für (später) beliebie viele Events
If \CBEventPause ; Pausesignal
\CB(#ET_Pause, \UserData)
WaitSemaphore(\CBEventPause)
\CB(#ET_Resume, \UserData)
EndIf
If \CBEventStop ; Stopsignal
\CB(#ET_Free, \UserData)
SignalSemaphore(\CBEventStop)
ProcedureReturn #Null
EndIf
\CBEvent = #False
EndIf
; Callback aufrufen und Ausgleichszeit errechnen
cTime = GetTimeMS()
\CB(#ET_Call, \UserData)
wTime = \Delay-GetTimeMS() + cTime
; Delay(<0) = warte unendlich
If wTime<0
wTime = #Null
EndIf
ForEver
EndWith
EndProcedure
; ------------------------------------------------------------------------------------
; Proceduren
; ------------------------------------------------------------------------------------
; Neuen Timer anlegen
Procedure ET_New(*Callback.ET_Procedure, Delay.i, UserData.i)
Protected *ET.ET_Data = AllocateMemory(SizeOf(ET_Data))
With *ET
\CB = *Callback
\Delay = Delay
\UserData = UserData
CreateThread(@_ET_Thread(), *ET)
ProcedureReturn *ET
EndWith
EndProcedure
; Timer pausieren
Procedure ET_Pause(*ET.ET_Data)
With *ET
If Not \CBEventPause
\CBEventPause = CreateSemaphore()
\CBEvent = #True
EndIf
EndWith
EndProcedure
; Timer fortsetzen
Procedure ET_Resume(*ET.ET_Data)
With *ET
If \CBEventPause
SignalSemaphore(\CBEventPause)
FreeSemaphore(\CBEventPause)
EndIf
EndWith
EndProcedure
; Timer freigeben
Procedure ET_Free(*ET.ET_Data)
With *ET
\CBEventStop = CreateSemaphore()
\CBEvent = #True
ET_Resume(*ET) ; Wenn nötig fortsetzen
WaitSemaphore(\CBEventStop)
FreeSemaphore(\CBEventStop)
FreeMemory(*ET)
EndWith
EndProcedure
DisableExplicit
Procedure Test(Event, Dummy)
MessageRequester("Call","Call")
EndProcedure
; Timer auf 1. Minut stellen
Timer = ET_New(@Test(), 1*60000, #Null)
Image = LoadImage(#PB_Any, #PB_Compiler_Home+"Examples\Sources\Data\CdPlayer.ico")
Dummy = OpenWindow(#PB_Any, 0, 0, 0, 0, "", #PB_Window_Invisible)
AddSysTrayIcon(#PB_Any, WindowID(Dummy), ImageID(Image))
Popup = CreatePopupMenu(#PB_Any)
MenuItem(1, "Exit")
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Menu
Select EventMenu()
Case 1
ET_Free(Timer)
End
EndSelect
Case #PB_Event_SysTray
Select EventType()
Case #PB_EventType_LeftClick, #PB_EventType_RightClick
DisplayPopupMenu(Popup, WindowID(Dummy))
EndSelect
EndSelect
Until #False
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster
PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Hab den Code aktualisiert, nun sollte das Exit sofort ausgeführt werden:Kaltstart hat geschrieben: Mite dem 'EXIT' habe ich noch Probleme. Er führt den Exit erst aus wenn der Timer wieder ausgelaufen ist.
http://www.purebasic.fr/german/viewtopi ... 815#244815
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster
PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
So funktioniert bei mir alles korrekt:
Gruß, Alex
Code: Alles auswählen
; ------------------------------------------------------------------------------------
; Easy Timer
; Einfacher leicht erweiterbarer Timer
; PB 4.3 +
; Alexander Aigner
; V 1.0
; ------------------------------------------------------------------------------------
; ------------------------------------------------------------------------------------
; Internes Zeugs
; ------------------------------------------------------------------------------------
; ------------------------------------------------------------------------------------
; HighRes - Timer
; ------------------------------------------------------------------------------------
EnableExplicit
Prototype HR_Time()
Structure _HR_Internal
StartTime.q
Res.d
EndStructure
Define _HR._HR_Internal
Global GetTimeMS.HR_Time
Procedure _HR_InitTime()
Shared _HR._HR_Internal
Protected Frequency.q
With _HR
If Not QueryPerformanceFrequency_(@Frequency)
ProcedureReturn #False
Else
QueryPerformanceCounter_(@\StartTime)
\Res = 1000/Frequency
ProcedureReturn #True
EndIf
EndWith
EndProcedure
Procedure _HR_Get()
Shared _HR._HR_Internal
Protected currentTime.q
With _HR
QueryPerformanceCounter_(@currentTime)
ProcedureReturn (currentTime-\StartTime)*\Res
EndWith
EndProcedure
Procedure _HR_oldPC_or_Linux()
ProcedureReturn ElapsedMilliseconds()
EndProcedure
; Initialisierung des High-Res Timers
CompilerIf #PB_Compiler_OS<>#PB_OS_Windows
GetTimeMS = @_HR_oldPC_or_Linux()
CompilerElse
If _HR_InitTime()
GetTimeMS = @_HR_Get()
Else
GetTimeMS = @_HR_oldPC_or_Linux()
EndIf
CompilerEndIf
; ------------------------------------------------------------------------------------
; Eigentlicher Timer
; ------------------------------------------------------------------------------------
Prototype ET_Procedure(Event, UserData)
Enumeration ; Sollte klar sein ...
#ET_Call
#ET_Pause
#ET_Resume
#ET_Free
EndEnumeration
Structure ET_Data
*CB.ET_Procedure
UserData.i
Delay.i
CBEvent.i
CBEventStop.i
CBEventPause.i
EndStructure
Procedure _ET_Thread(*ET.ET_Data)
Protected cTime, wTime
With *ET
wTime = \Delay
Repeat
If \CBEvent ; Nur 1. If-Abfrage für (später) beliebie viele Events
If \CBEventPause ; Pausesignal
\CB(#ET_Pause, \UserData)
WaitSemaphore(\CBEventPause)
\CB(#ET_Resume, \UserData)
EndIf
If \CBEventStop ; Stopsignal
\CB(#ET_Free, \UserData)
SignalSemaphore(\CBEventStop)
ProcedureReturn #Null
EndIf
\CBEvent = #False
EndIf
cTime = GetTimeMS()
While wTime>GetTimeMS()-cTime
Delay(1)
If \CBEvent ; Nur 1. If-Abfrage für (später) beliebie viele Events
If \CBEventPause ; Pausesignal
\CB(#ET_Pause, \UserData)
WaitSemaphore(\CBEventPause)
\CB(#ET_Resume, \UserData)
EndIf
If \CBEventStop ; Stopsignal
\CB(#ET_Free, \UserData)
SignalSemaphore(\CBEventStop)
ProcedureReturn #Null
EndIf
\CBEvent = #False
EndIf
Wend
; Callback aufrufen und Ausgleichszeit errechnen
cTime = GetTimeMS()
\CB(#ET_Call, \UserData)
wTime = \Delay-GetTimeMS() + cTime
; Delay(<0) = warte unendlich
If wTime<0
wTime = #Null
EndIf
ForEver
EndWith
EndProcedure
; ------------------------------------------------------------------------------------
; Proceduren
; ------------------------------------------------------------------------------------
; Neuen Timer anlegen
Procedure ET_New(*Callback.ET_Procedure, Delay.i, UserData.i)
Protected *ET.ET_Data = AllocateMemory(SizeOf(ET_Data))
With *ET
\CB = *Callback
\Delay = Delay
\UserData = UserData
CreateThread(@_ET_Thread(), *ET)
ProcedureReturn *ET
EndWith
EndProcedure
; Timer pausieren
Procedure ET_Pause(*ET.ET_Data)
With *ET
If Not \CBEventPause
\CBEventPause = CreateSemaphore()
\CBEvent = #True
EndIf
EndWith
EndProcedure
; Timer fortsetzen
Procedure ET_Resume(*ET.ET_Data)
With *ET
If \CBEventPause
SignalSemaphore(\CBEventPause)
FreeSemaphore(\CBEventPause)
EndIf
EndWith
EndProcedure
; Timer freigeben
Procedure ET_Free(*ET.ET_Data)
With *ET
\CBEventStop = CreateSemaphore()
\CBEvent = #True
ET_Resume(*ET) ; Wenn nötig fortsetzen
WaitSemaphore(\CBEventStop)
FreeSemaphore(\CBEventStop)
FreeMemory(*ET)
EndWith
EndProcedure
DisableExplicit
Procedure Test(Event, Dummy)
If Event = #ET_Call
MessageRequester("Call", "Call")
EndIf
EndProcedure
; Timer auf 1. Minut stellen
Timer = ET_New(@Test(), 1*60000, #Null)
Image = LoadImage(#PB_Any, #PB_Compiler_Home + "Examples\Sources\Data\CdPlayer.ico")
Dummy = OpenWindow(#PB_Any, 0, 0, 0, 0, "", #PB_Window_Invisible)
AddSysTrayIcon(#PB_Any, WindowID(Dummy), ImageID(Image))
Popup = CreatePopupMenu(#PB_Any)
MenuItem(1, "Exit")
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Menu
Select EventMenu()
Case 1
ET_Free(Timer)
End
EndSelect
Case #PB_Event_SysTray
Select EventType()
Case #PB_EventType_LeftClick, #PB_EventType_RightClick
DisplayPopupMenu(Popup, WindowID(Dummy))
EndSelect
EndSelect
Until #False
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster
PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Hallo cxAlex,
es funktioniert! (Natürlich
)
Auch wenn ich vom Ablauf her (noch) nicht alles verstehe ist das genau das was ich gesucht habe.
Auf der anderen Seite zeigt es mir aber auch, daß PureBasic genau die Programmiersprache ist, welche ich gesucht habe. (...und sich damit die Programmieranforderungen - welche ich habe - umsetzen lassen.)
Danke und Gruss
Kaltstart
es funktioniert! (Natürlich

Auch wenn ich vom Ablauf her (noch) nicht alles verstehe ist das genau das was ich gesucht habe.
Auf der anderen Seite zeigt es mir aber auch, daß PureBasic genau die Programmiersprache ist, welche ich gesucht habe. (...und sich damit die Programmieranforderungen - welche ich habe - umsetzen lassen.)
Danke und Gruss
Kaltstart