Suchprozedur verfällt nach 6 Sekunden in "Keine Rückmeldung"

Anfängerfragen zum Programmieren mit PureBasic.
OlderCoder
Beiträge: 134
Registriert: 18.03.2013 12:30
Wohnort: Bayerland
Kontaktdaten:

Suchprozedur verfällt nach 6 Sekunden in "Keine Rückmeldung"

Beitrag von OlderCoder »

Hallo allerseits,

Ich bin dabei, ein Programm zu schreiben, mit dem ich unter anderem auf der Festplatte nach Dateien suchen kann.
Bisher kann mein Programm zwar noch nicht nach Zeichenketten suchen, aber in einem vorgegebenen Pfad alle enthaltenen Ordner und Dateien zählen und den Suchpfad, wenn er sich ändert, anzeigen.

Das Problem ist jetzt, dass das Programm, sofern der Ordner genug Dateien enthält, nach etwa 6 Sekunden in der Titelleiste ein "Keine Rückmeldung" ausgibt. Gleichzeitig ändert sich der Windows-7-Mauszeiger zu dem blauen-Beschäftigt-Kreissymbol, wenn ich mit der Maus über das Programmfenster gehe.
Die von mir gewünschten Augaben wie Ordner- oder Dateien-Anzahl und der Suchpfad werden in dieser Zeit nicht ausgegeben, und das Programm ist auch nicht bedienbar (Schließsymbol).
Es ist nicht immer dieselbe Datei, bei der dieser Zustand beginnt. Bei C:\ z.B. mal nach 49416, mal nach 50027 Dateien.
Das Programm arbeitet aber weiter, wie man an den Festplattengeräuschen hören kann. Und wenn das Zählen abgeschlossen ist, ist das Programm auch wieder ansprechbar, und die Werte werden ausgegeben.
Testhalber hatte ich in die Such-Prozedur ein Delay eingebaut, um zu sehen, was passiert. Die Such-Geschwindigkeit ändert sich zwar sofort spürbar, aber die Zeit, bis das "Keine Rückmeldung" erscheint, bleibt nahezu gleich.

Hier die für die Suche relevanten Prozeduren. Die Variablen sind alle global.

Code: Alles auswählen

Procedure suchpfad()
  suchpfad$=""                                              ; Suchpfad zurücksetzen
  For i=0 To ebene                                         ; aktuellen Gesamt-Suchpfad zusammensetzen
    If i>1                                                      ; nur ab dem dritten Teil des Pfades
      suchpfad$+"\"                                         ; einen Backslash dazwischen
    EndIf  
    suchpfad$+namen$(i)                                 ; Suchpfad um neuen Ordnernamen ergänzen  
  Next i  
EndProcedure

Procedure suchen()
  ebene=0                                                   ; Ordnerebene zunächst ganz nach oben stellen    
  anzfile=0                                                   ; Anzahl der gefundenen Dateien auf 0
  anzfolder=0                                               ; Anzahl der gefundenen Ordner auf 0 
  If ExamineDirectory(ebene, suchpfad$,"*")                 ; wenn der Ordner geöffnet werden konnte 
    namen$(0)=suchpfad$                                     ; 1. Teil des Suchpfades auf den Anfangssuchpfad setzen
    SetGadgetText(16,suchpfad$)                    ; Anfags-Suchpfad ausgeben
    ; hier beginnt die eigentliche Suche  
weitersuchen:   
    While NextDirectoryEntry(ebene)                         ; Wenn es einen weiteren Eintrag gibt 
      h$ = DirectoryEntryName(ebene)                        ; Name des Eintrags holen
        ; Delay(200) ; Testverzögerung, nur wegen wegen Bugsuche, wird wieder gelöscht!  
      If DirectoryEntryType(ebene)=#PB_DirectoryEntry_File  ; wenn es eine Datei ist
        anzfile+1                                           ; Anzahl der durchsuchten Dateien zählen und ausgeben
        SetGadgetText(18,Str(anzfile))
          ; hier kommt später der Suchtest hin
      ElseIf h$<>"." And h$<>".."                           ; wenn es ein Ordner ist aber nicht "." oder ".." (??)
        anzfolder+1                                         ; Anzahl der durchsuchten Ordner zählen und ausgeben
        SetGadgetText(20,Str(anzfolder))
          ; hier kommt später der Suchtest hin  
        ebene+1                                             ; Suche +1 in die Tiefe
        namen$(ebene)=h$                                    ; neuen Eintragsnamen holen, in diesem Fall ein Ordner
        suchpfad()
        If ExamineDirectory(ebene,suchpfad$,"*")            ; wenn dieser Ordner auch zu öffnen war
        SetGadgetText(16,suchpfad$)                         ; neuen Pfad auch ausgeben
        Else  ; wenn nicht
          ebene-1  ; Ebene wieder zurück
          suchpfad()
        EndIf
      EndIf
    Wend
    ; es gibt keinen Eintrag mehr im aktuellen Verzeichnis
    FinishDirectory(ebene)                                  ; aktuelles Verzeichnis wieder schließen
    ebene-1                                                 ; Ebene wieder 1 nach oben
    If ebene >=0                                            ; das oberste Verzeichnis ist noch nicht fertig
      suchpfad()                                            ; verkürzten Suchpfad zusammensetzen
      SetGadgetText(16,suchpfad$)                           ; und ausgeben
      Goto weitersuchen                                     ; weitersuchen, Goto+Sprungmarke später ersetzen!
    EndIf
    ; Suche ist fertig
    DisableGadget(2,0)                                      ; Start-Taste einschalten
    DisableGadget(3,1)                                      ; Stop-Taste abschalten   
  Else                                                      ; keine Suche, wenn Anfangsverzeichnis nicht zu öffnen
    MessageRequester("Fehler!","Das Verzeichnis konnte nicht geöffnet werden!")  
  EndIf  
EndProcedure  
Vielleicht hat jemand von Euch eine Idee, warum dieses "Keine Rückmeldung", (das ich auch schon bei verschiedenen anderen Programmen erlebt habe) erscheint, und was man dagegegen tun kann.
Ich möchte unbedingt während des gesamten Suchvorgangs die vollständige Kontrolle über das Programm und den Suchvorgang behalten.
Danke!

Gruß
OlderCoder
Kevin
Beiträge: 236
Registriert: 11.06.2007 12:55

Re: Suchprozedur verfällt nach 6 Sekunden in "Keine Rückmeld

Beitrag von Kevin »

du fängst wahrscheinlich die Window-Events nicht ab... du musst also irgendwo ein WindowEvent() einsetzen

Code: Alles auswählen

Procedure suchpfad()
  suchpfad$=""                                              ; Suchpfad zurücksetzen
  For i=0 To ebene                                         ; aktuellen Gesamt-Suchpfad zusammensetzen
    If i>1                                                      ; nur ab dem dritten Teil des Pfades
      suchpfad$+"\"                                         ; einen Backslash dazwischen
    EndIf  
    suchpfad$+namen$(i)                                 ; Suchpfad um neuen Ordnernamen ergänzen  
  Next i  
EndProcedure

Procedure suchen()
  ebene=0                                                   ; Ordnerebene zunächst ganz nach oben stellen    
  anzfile=0                                                   ; Anzahl der gefundenen Dateien auf 0
  anzfolder=0                                               ; Anzahl der gefundenen Ordner auf 0 
  If ExamineDirectory(ebene, suchpfad$,"*")                 ; wenn der Ordner geöffnet werden konnte 
    namen$(0)=suchpfad$                                     ; 1. Teil des Suchpfades auf den Anfangssuchpfad setzen
    SetGadgetText(16,suchpfad$)                    ; Anfags-Suchpfad ausgeben
    ; hier beginnt die eigentliche Suche  
weitersuchen:   
    While NextDirectoryEntry(ebene)                         ; Wenn es einen weiteren Eintrag gibt 
      h$ = DirectoryEntryName(ebene)                        ; Name des Eintrags holen
        ; Delay(200) ; Testverzögerung, nur wegen wegen Bugsuche, wird wieder gelöscht!  
      If DirectoryEntryType(ebene)=#PB_DirectoryEntry_File  ; wenn es eine Datei ist
        anzfile+1                                           ; Anzahl der durchsuchten Dateien zählen und ausgeben
        SetGadgetText(18,Str(anzfile))
          ; hier kommt später der Suchtest hin
      ElseIf h$<>"." And h$<>".."                           ; wenn es ein Ordner ist aber nicht "." oder ".." (??)
        anzfolder+1                                         ; Anzahl der durchsuchten Ordner zählen und ausgeben
        SetGadgetText(20,Str(anzfolder))
          ; hier kommt später der Suchtest hin  
        ebene+1                                             ; Suche +1 in die Tiefe
        namen$(ebene)=h$                                    ; neuen Eintragsnamen holen, in diesem Fall ein Ordner
        suchpfad()
        If ExamineDirectory(ebene,suchpfad$,"*")            ; wenn dieser Ordner auch zu öffnen war
        SetGadgetText(16,suchpfad$)                         ; neuen Pfad auch ausgeben
        Else  ; wenn nicht
          ebene-1  ; Ebene wieder zurück
          suchpfad()
        EndIf
      EndIf
    While WindowEvent()<>0 : Wend
    Wend
    ; es gibt keinen Eintrag mehr im aktuellen Verzeichnis
    FinishDirectory(ebene)                                  ; aktuelles Verzeichnis wieder schließen
    ebene-1                                                 ; Ebene wieder 1 nach oben
    If ebene >=0                                            ; das oberste Verzeichnis ist noch nicht fertig
      suchpfad()                                            ; verkürzten Suchpfad zusammensetzen
      SetGadgetText(16,suchpfad$)                           ; und ausgeben
      Goto weitersuchen                                     ; weitersuchen, Goto+Sprungmarke später ersetzen!
    EndIf
    ; Suche ist fertig
    DisableGadget(2,0)                                      ; Start-Taste einschalten
    DisableGadget(3,1)                                      ; Stop-Taste abschalten   
  Else                                                      ; keine Suche, wenn Anfangsverzeichnis nicht zu öffnen
    MessageRequester("Fehler!","Das Verzeichnis konnte nicht geöffnet werden!")  
  EndIf  
EndProcedure 
OlderCoder
Beiträge: 134
Registriert: 18.03.2013 12:30
Wohnort: Bayerland
Kontaktdaten:

Re: Suchprozedur verfällt nach 6 Sekunden in "Keine Rückmeld

Beitrag von OlderCoder »

Danke, Kevin!!!
Selten ist ein Problem so schnell gelöst worden.
Einer der nächsten Schritte wäre gewesen, den Stop-Button während der Suche abzufragen, und dann wäre mein Problem automatisch entfernt worden.
Aber so weiß ich jetzt jedenfalls Bescheid.
Eine kurze Abfrage der Windows Events und der Schlafmodus hört auf.

Ist aber schon seltsam, dass man die deshalb abfragen muss. Ich dachte, man kann, wenn man sie braucht.

Danke!

Gruß
OlderCoder
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3873
Registriert: 13.09.2004 17:48
Kontaktdaten:

Re: Suchprozedur verfällt nach 6 Sekunden in "Keine Rückmeld

Beitrag von bobobo »

nee .. man muss (sollte) wenn man ein Fenster benutzt auch wenn man die nicht weiter auswertet.

Allerdings ist WhileWindowEvent():Wend schon ein SpezialFall
der für nur darstellende Fenster ausreichend sein könnte aber sicher nicht
für eine korrekte EventBehandlung die alles mögliche abfangen soll.

Benutz möglichst immer eine EreignisProzedur

WaitwindowEvent()
"geht" auch mit Parameter
WaitwindowEvent(200)
wartet dann 200 mSek auf ein Ereignis
und dann weiter zuhuschen
die folgende EreignisSchleife wird z.B. alle 10 mSek durchgerannt

Code: Alles auswählen

Repeat
  Event=WaitWindowEvent(10)
  Select Event
    Case #PB_Event_CloseWindow
      Quit+1
    Case #PB_Event_Gadget
      ;mach irgendwas
    Case #PB_Event_Timer
      ;mach was anderes
    Case #PB_Event_Menu
      ;mach was entsprechendes
    Case #PB_Event_SizeWindow
      ;mach was anderes entsprechendes
    Default
      ;egal
  EndSelect
  ;hier kann weiterer ProgrammCode stehen
Until Quit
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
OlderCoder
Beiträge: 134
Registriert: 18.03.2013 12:30
Wohnort: Bayerland
Kontaktdaten:

Re: Suchprozedur verfällt nach 6 Sekunden in "Keine Rückmeld

Beitrag von OlderCoder »

So mache ich das normalerweise auch immer.
In diesem Fall sieht meine Abfrage innerhalb der Suchprozedur allerdings so aus:

Code: Alles auswählen

If WindowEvent()=#PB_Event_Gadget And EventGadget()=3 ; wenn der Stop-Button geklickt wurde
   stop=1                                             ; Stop-Flag setzen
EndIf
Damit kann ich die Suche jederzeit vorzeitig abbrechen. Das Stop-Flag wird an anderer Stelle der Prozedur dann verwertet.
Da die Suchroutine bei der Arbeit ist, wäre ein WaitWindowEvent(<Verzögerung>) vermutlich nicht das richtige, wo auf ein Event gewartet wird, oder?

Kevin wollte mit dem

Code: Alles auswählen

 While WindowEvent()<>0 : Wend
wohl nur den Event-Puffer zu leeren, um mein Problem zu beseitigen, was natürlich dann keine Möglichkeit der Auswertung von Events mehr zulässt.
Und ein Abbruch der Suche wollte ich schon einbauen.
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3873
Registriert: 13.09.2004 17:48
Kontaktdaten:

Re: Suchprozedur verfällt nach 6 Sekunden in "Keine Rückmeld

Beitrag von bobobo »

WaitWindowEvent(..) mit dem Timeout könnte gehen wenn der Timeout
klein genug ist.

Ich tät die Suchroutine in einen Thread packen,
den Fortschritt in einer globalen Variablen ausgeben
und diese vermutlich mit einem TimerEvent in der
EventSchleife abfragen.

Das Endergebnis würde ich erst nach Abschluss der Suchroutine
ausgeben wollen und bis dahin etwas Animation (Abfrage in der
Eventschleife s.o.), damit man sieht, dass da was werkelt.

Oder so ähnlich
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
OlderCoder
Beiträge: 134
Registriert: 18.03.2013 12:30
Wohnort: Bayerland
Kontaktdaten:

Re: Suchprozedur verfällt nach 6 Sekunden in "Keine Rückmeld

Beitrag von OlderCoder »

Über das Thema Threads hab ich leider noch keinen blassen Schimmer.

Ich mag es, wenn ich sehen kann, wo das Programm gerade sucht, wieviel Dateien und Ordner es schon durchsucht hat usw.
Ist so eine Marotte von mir.
Ich weiß nur nicht, wieviele Ausgaben dieser Art ich dem Programm zumuten kann, ohne dass die Suchgeschwindigkeit spürbar leidet.
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3873
Registriert: 13.09.2004 17:48
Kontaktdaten:

Re: Suchprozedur verfällt nach 6 Sekunden in "Keine Rückmeld

Beitrag von bobobo »

ausprobieren
je weniger Ausgabe desto flott
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Antworten