Programm hängt sich bei Schleige auf?



  • Hi
    ich hab folgenden code: (bitte auch die kommentare lesen damit ihr auch den zusammenhang versteht)

    void __fastcall TForm1::ControleDirSize(unsigned long DirSize, AnsiString Dir)
    {
            unsigned long OldDirSize = DirSize; // DirSize ist eine Variable in der die größe eines Verzeichnisses steht
            second = 0; //für einen timer
            minute = 0; //auch für einen timer
            while(minute <= TimeInMinutes) //schleife solang der timer nicht eine gewisse zeit erreicht hat
            {
                    if(OldDirSize == GetDirSize(Dir)) { // GetDirSizw ist eine funktion die die Verzeichnisgröße zurückgibt. 
    //wenn sich die verzeichnisgröße nicht verändert mach einen haufen töne
                            for(int i=0;i<=30;i++) {
                                    MessageBeep(1);
                            }
                    }
                    Sleep(50000); // warte ein bischen bis zum nächsten check der verzeichnisgröße
            }
    }
    

    das problem ist jetzt das sich mein programm bei der while schleife aufhängt. es reagiert nicht mehr und ich kann es nichtmal mehr normal schließen. an der cpu auslastung liegts nicht die ist nicht so hoch. weiß wer vielleicht woran das liegt?

    mfg sauron



  • Mein Problem ist, dass ich nicht weiss wo ich anfangen soll...

    Hast du die Schleife überhaupt schon mal mental durchgespielt?
    Was ist die Schleifenbedingung?
    Andersrum: was ist das Schleifenabbruchkriterium, und was müsste passieren damit es erreicht wird? Was immer es ist passiert innerhalb der Schleife offensichtlich nicht 😉

    Auf das Sleep() will ich erst garnicht eingehen weil ich nicht durchblicke warum du es haben willst, gebe aber zu bedenken, dass 50.000 etwa 50 Sekunden Stillstand bedeuten.



  • Wie groß ist TimeInMinutes? Es kann sein, dass es mit dem Wertebereich Probleme gibt und "minute <= TimeInMinutes" deshalb immer erfüllt wird...



  • Hi
    @Tilsiter
    Also ich hab die schleife durchgespielt und sie tut im prinzip nix anderes als eine bestimmte zeit lang(while minute <= TimeInMinutes) die frühere Größe eines Verzeichnisses mit der derzeitigen zu vergleichen.
    das sleep ist deswegen da da das überprüfen der verzeichnisgröße vorallem bei strukturen mit viele unterverzeichnissen viel rechenleistung frisst und durch das sleep wird die überprüfung nicht so oft durchgeführt.

    @Mastah
    TimeInMinutes wird aus einer Usereingabe gelesen aber die is net zu groß. Es stimmt aber schon das die Schleife einige Zeit dauert(10 minuten) aber trozdem darf es doch nicht passieren das ich in dieser zeit nichtmal das programmfenster verschieben kann oder? hier übrigends mal diese timerfunktion. die "minute" variable wird durch sie gesetzt. vielleicht findet ihr ja hier etwas.

    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
            second = second + 1;
            if (second == 60)
            {
                    second = 0;
                    minute = minute + 1;
            }
            LblFolderSize->Caption = second;
            if(minute == TimeInMinutes)
            {
                    LblFolderSize->Caption = "Zeit abgelaufen";
            }
    }
    

    mfg sauron



  • hallo,

    du willst im prinzip wissen, ob sich im verzeichnis etwas verändert. da dies zu jeder zeit geschehen kann ist es nicht sinnvoll das mit einem timer zu testen. verwende einen thread dafür. im thread kannst du dann die funktionen
    der api
    -FindFirstChangeNotification
    -WaitForSingleObject
    -FindNextChangeNotification

    verwenden um zu prüfen, ob eine datei hinzugekommen bzw. gelöscht wurde oder sonst was du prüfen willst (kannst auch auf attributänderungen der dateien prüfen). du solltest also wissen wie man mit dem TThread object der vcl arbeitet, innerhalb des threads kannst du dann in der execute mthode etwa etwas in dieser art einbauen:

    changehandle:=FindFirstChangeNotification(PChar(watchpath),FALSE,FILE_NOTIFY_CHANGE_FILE_NAME); 
        if changehandle <> INVALID_HANDLE_VALUE then begin 
          while True do begin  // normalerweise eine Endlosschleife 
            if WaitForSingleObject(changehandle,500)= WAIT_OBJECT_0 then begin 
               synchronize(RefreshListbox); 
            end; 
            FindNextChangeNotification(changehandle); 
            if Terminated then break; 
          end;
    

    dann hast du null prozzsorauslastung, die oberfläche bleibt bewegbar und es wird korrekt nach änderungen geprüft, denn bei der timer methode möchte ich gar nicht wisse, was da alles schief laufen kann um dann ein falsches resultat zu haben und mit diesem dann auch noch weiterzuarbeiten...

    mfg
    murph



  • hast du dir mal die hilfe zu Sleep durchgelesen?

    Sleep unterbricht die ausführung eines threads, d.h. deiner anwendung in diesem fall, und erst nach ablauf der angegebenen zeit (in millisekunden) wird der thread (deine anwendung) fortgesetzt. wenn du Sleep mit grossen werten verwendest, dann "hängt" sich das programm scheinbar auf.

    @murphy

    wir sind hier im c++-forum und nicht im delphi-forum!!!



  • Hi
    danke für den tipp mit der api aber ich möchte gerne wissen was an meinem prog net stimmt. an dem sleep liegts nicht wenn ich das wegtu dann hab ich genau das selbe problem. es scheint also daran zu liegen das er in dieser schleife steckt aber ich find da nichts falsches.
    hat jemand vielleicht ne andere lösung?

    mfg sauron





  • So lange die Bedingung für die While- Schleife nicht erfüllt ist, bewegt sich der Prozessor immer in der While- Schleife (also manchmal bis zu 10 Min).

    Es scheint, als wäre der PC abgestützt, obwohl er nur immer in der While- Schleife herumtollt.

    Ich würde deine Sache auch mit einem Thread verbinden, wie es murphy angedeutet hat. Damit kannst du auch während der Abfrage weiterarbeiten.



  • Und wieso rufst du ControleDirSize nicht direkt in einem Timer auf der einmal pro Minute loslegt?
    Dann entfällt der Sleep Kram doch und mit Threads musst du dich auchnicht rumärgern.


Anmelden zum Antworten