Seite 1 von 2

Threads ohne WindowEvent und Waitwindowevent möglich?

Verfasst: 25.07.2008 17:54
von marco2007
Hi,

wie macht eine Thread ohne WindowEvent oder Waitwindowevent?
Wenn`s eine Hauptschleife mit WaitwindowEvent gibt und mann ruft den Thread auf, gibt`s eh keine Probleme.
Bei meinem Programm wird am Anfang (vor der Hauptschleife) `ne Menge an Daten geladen. Den Fortschitt möchte ich mittels 2 Progressbargadgets machen.
Nur funktiniert das nicht wirklich.

Hier ein kurzer Code, damit ihr wißt, was ich meine:

Code: Alles auswählen

Procedure test(wert)
For j=0 To 100
  SetGadgetState(0, j)
  Delay(100)
Next  
EndProcedure

If OpenWindow(0, 400,400,200,200, "") And CreateGadgetList(WindowID(0))
  ProgressBarGadget(0, 20, 20, 160, 20, 0, 20, 8)
  ProgressBarGadget(1, 20, 60, 160, 20, 0, 20)
EndIf

CreateThread(@test(), 20)
For i=0 To 20
;WindowEvent() ; -> Ohne dieser Zeile geht`s gar nicht -> mit ist`s auch nicht schön
  SetGadgetState(1, i)
  Delay(200)
Next    


Repeat:Until WaitWindowEvent()=#WM_CLOSE
Hat vielleicht jemand einen Tipp, was ich machen soll oder kann?

lg
Marco

Verfasst: 25.07.2008 17:58
von Kaeru Gaman
mittels globalen kommunikationsvariablen:

die Lade-threads setzen globale Variablen um den Fortschritt "mitzuzählen".

der Hauptthread mit WaitWindowEvent(timeout) aktualisiert die Progressbars anhand dieser Globals.
ein timeout zwischen 10 und 100 ist geeignet für so einen zweck.

eigentlich würde man für sowas ein Semaphor verwenden,
aber so eine globale Variable ist praktisch ein abgespecktes Semaphor,
wenn man sie richtig handhabt.

Verfasst: 25.07.2008 18:08
von marco2007
Naja, so ähnlich hatte ich`s gelöst - nur wird das ganze dann so extrem langsam.
Der Thread sollte unabhängig vom Rest laufen, ein Pogressbargadget also "endlos". Der Nutzer soll eigentlich nur sehen, daß sich etwas tut. Sprich: Das erste ProgresBarGadget ist eigentlich funktionsmäßig sinnlos.
Das zweite zeigt den wirklichen Fortschritt.

Verfasst: 25.07.2008 18:16
von Kaeru Gaman
> nur wird das ganze dann so extrem langsam.
hm... versteh ich garnicht...

PS:
was ist denn diese 8 dort?

Verfasst: 25.07.2008 18:28
von Kaeru Gaman
PPS:
war hältst du hiervon?

Code: Alles auswählen

#Gesamt = 5000
Global GlobalCounter.l
Global BreakFlag.l = 0

Procedure test(wert)
For j=0 To #Gesamt
  GlobalCounter = j
  Delay(5)
  If BreakFlag
    Break
  EndIf
Next 
EndProcedure

If OpenWindow(0, 400,400,200,200, "") And CreateGadgetList(WindowID(0))
  ProgressBarGadget(0, 20, 20, 160, 20, 0, 100)
  ProgressBarGadget(1, 20, 60, 160, 20, 0, #Gesamt)
EndIf

CountThread.l = CreateThread(@test(), 0)

Repeat
  EventID = WaitWindowEvent(20)
  SetGadgetState(0, GlobalCounter % 100)
  SetGadgetState(1, GlobalCounter)
  
Until EventID = #PB_Event_CloseWindow

BreakFlag = 1               ; Unterbrecher setzen
WaitThread( CountThread )   ; auf Beenden warten

End

Verfasst: 25.07.2008 18:28
von marco2007
Ursprünglich habe ich einfach ein TextGadget + Setgadgettext(i+1) verwendet, aber nachdem die Datenmenge größer und größer wurde, wurde mir das zu langsam. Da bei Abhängigkeiten der Rechner logischerweise mehr rechnen muss.
Ja uns so ähnlich ist mit dem Thread auch, wenn man`s von etwas abhängig macht. Darum möchte ich den Thread komplett unabhängig laufen lassen. Aber das funktioniert leider anscheiend nicht so ohne Probleme.


Edit: Sah gerade Dein Post -> Genau so hatte ich`s.

Verfasst: 25.07.2008 18:30
von edel
Wenn`s eine Hauptschleife mit WaitwindowEvent gibt und mann ruft den Thread auf, gibt`s eh keine Probleme.
Wenn es da keine Probleme gibt, was hindert dich daran es so zu machen?
Schreibe dir doch einfach eine "Hauptschleife" fuer das laden von was auch
immer und eine fuer das eigentliche Programm. Die erste Schleife verlaesst
du, nachdem du alles geladen hast. Danach springt das Programm direkt in
die 2. Schleife und fertig ist der Apfel.

Verfasst: 25.07.2008 18:32
von Kaeru Gaman
nochmal aufgepeppt:

Code: Alles auswählen

#Gesamt = 100000000
#Teiler = 1000000
Global GlobalCounter.l
Global BreakFlag.l = 0

Procedure test(wert)
  For j=0 To #Gesamt
    GlobalCounter = j
    If BreakFlag
      Break
    EndIf
  Next 
EndProcedure

If OpenWindow(0, 400,400,200,200, "") And CreateGadgetList(WindowID(0))
  ProgressBarGadget(0, 20, 20, 160, 20, 0, #Teiler)
  ProgressBarGadget(1, 20, 60, 160, 20, 0, #Gesamt)
  TextGadget(2, 20, 100, 160, 20, "", #PB_Text_Border | #PB_Text_Right)
EndIf

CountThread.l = CreateThread(@test(), 0)

Repeat
  EventID = WaitWindowEvent(20)
  SetGadgetState(0, GlobalCounter % #Teiler)
  SetGadgetState(1, GlobalCounter)
  SetGadgetText(2, Str(GlobalCounter))
  
Until EventID = #PB_Event_CloseWindow

BreakFlag = 1               ; Unterbrecher setzen
WaitThread( CountThread )   ; auf Beenden warten

End
EDIT: pimped once more

Verfasst: 25.07.2008 18:34
von marco2007
Das Problem: Das Programm ist jetzt schon ziemlich groß und ich hasse es schon :evil: . Dafür müßte ich einiges umschreiben.
Und eigentlich möchte ich es abschließen. Ein paar Sachen möchte ich noch verbessern bzw. verschönern.
Beim nächsten Mal fange ich sicher anders an :mrgreen:

Verfasst: 25.07.2008 18:53
von marco2007
Danke erstmal. Wenn ich`s gescheit machen soll, dann muss ich wohl über `ne 2. Schleife nachdenken. Schade, daß Threads nicht ohne Waitwindowevents funken.

Danke Euch!!