Kleines Thread-Demo

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Dostej
Beiträge: 529
Registriert: 01.10.2004 10:02
Kontaktdaten:

Kleines Thread-Demo

Beitrag von Dostej »

Also, da immer wieder Fragen bezüglich Treads im Formum auftauchen, habe ich mal gedacht, ich schreibe ne kleine Demo, die zeigt wie man verschiedene Dinge in und mit Thread machen kann (öffnen, schliessen, selber schliessen, überwachen)
Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Ich weiss nicht ob der Code effizient oder elegant ist. Er funktioniert tut er denke ich und beispielhaft soll er sein (weniger als Vorbild... er könnte schon besser strukturiert sein - weiss ich)
Falls es so was schon gibt, dann soll ein Mod das doch einfach wieder löschen.

Ansonsten hab ich noch ne Frage dazu:
Wenn ich schnell hintereinander mehrere Threads öffne, "hängen" die einzelnen Threads manchmal.
Ich versteh nicht ganz warum bzw. wo der Fehler liegt? (Hilfe!)

Code: Alles auswählen

; PureBasic Visual Designer v3.90 build 1361

;- Window Constants
Enumeration
  #Window_10
  
  
  #Window_0
EndEnumeration

;- Gadget Constants
Enumeration
  #String_10
  #Button_10
  #Button_11
  #Button_12
  #LOG
  
  #Button_0
  #String_0
EndEnumeration


; Variablen
Dim Thread_ID.l(10, 1) ; 0 = threadID  1=1, wenn thread geschlossen wurde

; Proceduren
Procedure Open_ThreadWindow(nr.l)
  If OpenWindow(#Window_0, 200 + nr * 30, 300 + nr * 30, 286, 184,  #PB_Window_SystemMenu | #PB_Window_TitleBar , "Thread test " + Str(nr))
    If CreateGadgetList(WindowID())
      ButtonGadget(#Button_0, 80, 160, 110, 20, "OK")
      StringGadget(#String_0, 10, 10, 260, 130, "", #ES_MULTILINE)
      
      Repeat 
        Event = WindowEvent()
        If Thread_ID(nr, 1) = 2 ; wenn der Thread geschlossen werden soll
          Event = #PB_EventCloseWindow ; beenden
        EndIf
        
        If Event = #PB_EventGadget
          GadgetID = EventGadgetID()
          
          If GadgetID = #Button_0
            Event = #PB_EventCloseWindow
            
          ElseIf GadgetID = #String_0
            Debug "GadgetID: #String_0"
            
          EndIf 
        EndIf
        Delay(5)
      Until Event = #PB_EventCloseWindow
      Event = 0
      CloseWindow(#Window_0)
      Thread_ID(nr, 1) = 1
    EndIf
  EndIf
EndProcedure
Procedure Set_Thread_Log()
  ; Frage die Threads ab
  ClearGadgetItemList(#LOG)
  For x = 0 To 10
    If Thread_ID(x, 0) <> 0
      AddGadgetItem(#LOG, -1, Str(x) + " Thread running: " + Str(Thread_ID(x, 0)))
    Else
      AddGadgetItem(#LOG, -1, Str(x) + " Thread nicht aktiv")
    EndIf
  Next
EndProcedure
Procedure Check_Thread()
  c.l = 0
  For x = 0 To 10
    If Thread_ID(x, 1) = 1 ; wenn thread sich abgemeldet hat
      Debug "thread geschlossen: " + Str(x) + ": " + Str(Thread_ID(x, 1))
      AddGadgetItem(#String_10, -1, "thread geschlossen " + Str(x))
      c + 1
      Thread_ID(x, 0) = 0
      Thread_ID(x, 1) = 0
    EndIf
  Next
  If c <> 0
    Set_Thread_Log()
  EndIf
EndProcedure
Procedure Thread_Master()
  If OpenWindow(#Window_10, 216, 0, 587, 291,  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , "Thread master")
    If CreateGadgetList(WindowID())
      ListViewGadget(#String_10, 10, 10, 360, 210)
      ListViewGadget(#LOG, 380, 10, 200, 210)
      ButtonGadget(#Button_12, 120, 260, 100, 20, "Close Thread")
      ButtonGadget(#Button_10, 300, 260, 70, 20, "Quit")
      ButtonGadget(#Button_11, 120, 230, 100, 20, "New Thread")
      
      
      Repeat 
        Event = WindowEvent() 
        Check_Thread()
        If Event = #PB_EventGadget
          GadgetID = EventGadgetID() 
          If GadgetID = #String_10 
            
          ElseIf GadgetID = #Button_10
            ; lösche alle noch aktiven Threads
            For x = 0 To 10
              If Thread_ID(x, 0) <> 0
                Thread_ID(x, 1) = 2
              EndIf
            Next
            Delay(20)
            Event = #PB_EventCloseWindow
            
          ElseIf GadgetID = #Button_12 ; kill Thread
            t = GetGadgetState(#LOG)
            If t > -1 ; wenn ein Item markiert
              If Thread_ID(x, 0) <> 0; wenn Thread aktiv
                Thread_ID(t, 1) = 2 ; sende Schliessen
              EndIf
            EndIf
            
          ElseIf GadgetID = #Button_11
            ; hole freie threadnr
            For x = 0 To 10
              If Thread_ID(x, 0) = 0
                ThreadNr = x
                Break
              EndIf
            Next
            If ThreadNr <=10
              AddGadgetItem(#String_10, -1, "start thread " + Str(ThreadNr))
              Thread_ID(ThreadNr, 0) = CreateThread(@Open_ThreadWindow(), ThreadNr)
              Set_Thread_Log()
            EndIf
          EndIf 
        EndIf 
        Delay(5)
      Until Event = #PB_EventCloseWindow
    EndIf
  EndIf
EndProcedure


; run Prog
Thread_Master()

End