Seite 1 von 1
"Hängengebliebenes" WebGadget selbständig neu starten
Verfasst: 13.07.2018 15:18
von Delle
Hallo,
ich verwende in einem Thread folgenden Code:
Code: Alles auswählen
SetGadgetText(#Browser,GetDatabaseString(#DB, DatabaseColumnIndex(#DB, "url")))
While GetGadgetAttribute(#Browser, #PB_Web_Busy):Delay(100):Wend
Erst wenn das WebGadget vollständig geladen ist, soll es also weitergehen...
Manchmal bleibt es aber im While:Wend stecken, da anscheinend irgendwie keine Mitteilung via #PB_Web_Busy kommt (die Seite wurde aber definitiv vollständig geladen).
Die Idee wäre jetzt im While:Wend vielleicht die Zeit hochzuzählen und wenn es 30 Sekunden erreicht hat (=hängt also), dann soll ein Refresh für das Webgadget angestoßen werden.
Code: Alles auswählen
StartTime.q = ElapsedMilliseconds()
While GetGadgetAttribute(#Browser, #PB_Web_Busy)
Delay(100)
If(ElapsedMilliseconds() - StartTime)>30000
SetGadgetState(#Browser,#PB_Web_Refresh)
StartTime.q = ElapsedMilliseconds()
Debug "Ist hängengeblieben, Refresh!"
EndIf
Wend
Kann man das so umsetzen oder hat jemand andere Ideen?
Danke!
Re: "Hängengebliebenes" WebGadget selbständig neu starten
Verfasst: 13.07.2018 15:50
von NicTheQuick
Abgesehen davon, dass man Gadgets aus einem Thread heraus nicht manipulieren soll und es dadurch sowieso zu unvorhersehbaren Probleme kommen kann, ist es notwendig regelmäßig Events abzuarbeiten. Du musst also (Wait)WindowEvent() im Hauptthread nutzen, damit die Interna auch aktualisiert werden. Darunter wird sich mit Sicherheit auch das Flag #PB_Web_Busy befinden.
Re: "Hängengebliebenes" WebGadget selbständig neu starten
Verfasst: 13.07.2018 15:56
von Delle
NicTheQuick hat geschrieben:Abgesehen davon, dass man Gadgets aus einem Thread heraus nicht manipulieren soll und es dadurch sowieso zu unvorhersehbaren Probleme kommen kann, ist es notwendig regelmäßig Events abzuarbeiten. Du musst also (Wait)WindowEvent() im Hauptthread nutzen, damit die Interna auch aktualisiert werden. Darunter wird sich mit Sicherheit auch das Flag #PB_Web_Busy befinden.
Also die Events werden nach wie vor im Hauptteil abgearbeitet:
Code: Alles auswählen
Repeat
EventID = WaitWindowEvent(50)
If EventID=#PB_Event_Gadget And EventGadget()=#Suche
...
EndIf
Until EventID = #PB_Event_CloseWindow
Ich kann aber im 2. Thread dann nicht wieder in den Hauptthread springen, nur um dort ein Gadget mit einer URL zu befüllen usw.
Re: "Hängengebliebenes" WebGadget selbständig neu starten
Verfasst: 13.07.2018 16:07
von Kiffi
Probier's mal hiermit
[PseudoCode, nicht getestet]:
Code: Alles auswählen
Procedure ReloadBrowser(Browser, Url.s)
Static ReloadBrowserCounter
If ReloadBrowserCounter = 5
ReloadBrowserCounter = 0
Debug "Jetzt habe ich keinen Bock mehr"
ProcedureReturn
EndIf
SetGadgetText(Browser, Url)
StartTime = ElapsedMilliseconds()
bTimeout = #False
While GetGadgetAttribute(Browser, #PB_Web_Busy)
Delay(100)
If(ElapsedMilliseconds() - StartTime) > 30000
Debug "Ist hängengeblieben, Refresh!"
bTimeout = #True
EndIf
Wend
If bTimeout
ReloadBrowserCounter + 1
ReloadBrowser(Browser, Url)
EndIf
EndProcedure
Re: "Hängengebliebenes" WebGadget selbständig neu starten
Verfasst: 13.07.2018 17:17
von NicTheQuick
Du kannst der Hauptschleife auch Daten über PostEvent() senden und sie führt dann aus, was du in deinem Thread machst. Das wäre zumindest das Vorgehen wie man es unter Linux und Mac korrekt umsetzen würde. Ich habe das Beispiel jetzt aber mit einem EditorGadget() gemacht.
Code: Alles auswählen
Enumeration
#mainWindow
EndEnumeration
Enumeration
#textGadget
EndEnumeration
Enumeration #PB_EventType_FirstCustomValue
#eventTextChange
EndEnumeration
Procedure changeContent(gadget.i)
Protected i.i, *pString.String
Repeat
*pString = AllocateStructure(String)
*pString\s = "Der Wert ist " + i
i + 1
PostEvent(#PB_Event_Gadget, #mainWindow, gadget, #eventTextChange, *pString)
Delay(1000)
ForEver
EndProcedure
OpenWindow(#mainWindow, 0, 0, 400, 300, "test", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
EditorGadget(#textGadget, 0, 0, 400, 300)
CreateThread(@changeContent(), #textGadget)
Define *pString.String
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #PB_Event_Gadget
Select EventType()
Case #eventTextChange
*pString = EventData()
SetGadgetText(#textGadget, *pString\s)
FreeStructure(*pString)
EndSelect
EndSelect
ForEver
Re: "Hängengebliebenes" WebGadget selbständig neu starten
Verfasst: 13.07.2018 23:16
von mk-soft
Arbeite viel mit Threads und habe mir dieses Modul geschrieben und aus Threads die GUI zu ändern...
Link:
viewtopic.php?f=8&t=29728
Re: "Hängengebliebenes" WebGadget selbständig neu starten
Verfasst: 26.07.2018 21:43
von Delle
So, ich hab es mal aus dem Thread rausgenommen, es läuft jetzt also in der Hauptschleife.
Nachteil (aber nicht so wild): Programm lässt sich nur mittels Taskmanager abbrechen.
Code: Alles auswählen
OpenWindow(0, 0, 0, 1200, 800, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
WebGadget(#Browser, 10, 45, 1000, 650, "about:blank"):MyWebGadget.IWebBrowser2=GetWindowLong_(GadgetID(#Browser),#GWL_USERDATA):MyWebGadget\put_Silent(#True):SetGadgetAttribute(#Browser,#PB_Web_BlockPopups,1)
DisableGadget(#Browser,1)
While WindowEvent():Wend
Repeat
EventID = WaitWindowEvent(50)
If EventID=#PB_Event_Gadget And EventGadget()=#Suche
If GetGadgetText(#Suche)="Suche starten"
SetGadgetText(#Suche, "Suche anhalten")
EndIf
Repeat
SetGadgetText(#Browser,GetDatabaseString(#DB, DatabaseColumnIndex(#DB, "url")))
Debug FormatDate("%hh:%ii", Date())+" Warten bis Seite fertig geladen"
StartTime.q = ElapsedMilliseconds()
While GetGadgetAttribute(#Browser, #PB_Web_Busy):While WindowEvent():Wend
If(ElapsedMilliseconds() - StartTime)>60000:Debug FormatDate("%hh:%ii", Date())+" ***** Ist hängengeblieben, Abbruch!":Break:EndIf
Wend
Debug FormatDate("%hh:%ii", Date())+" Fertig! :-)"
; ...
ForEver
EndIf
Until EventID = #PB_Event_CloseWindow
Nach 60 Sekunden soll er abbrechen, da die Seite wohl "hängt".
Witzigerweise checkt er aber erst teilweise nach 5 Minuten (nicht 60 Sekunden) das nichts passiert ist...
21:31 Warten bis Seite fertig geladen
21:36 ***** Ist hängengeblieben, Abbruch!
21:36 Fertig!
Muss die While/Wend-Schleife wohl anders gestaltet werden?
Re: "Hängengebliebenes" WebGadget selbständig neu starten
Verfasst: 27.07.2018 08:45
von RSBasic
Löst zwar nicht das Problem, aber verwende bitte nicht GetWindowLong_(), sondern GetWindowLongPtr_(). (64 Bit-Kompatibilität)