Lang andauernde Schleife , und trozdem noch Fesnter bedienbar lassen??



  • Hallo ihr,

    ich habe in einem Berechnungs-Dialog eine schleife die mehrer sekunden andauern kann. Und während die schleife läuft können ja keine Messages verarbeitet werden.

    Wie würdert ihr das lösen?? Ab und zu mal die Messageloop in der schleife aufrufen, oder die schleife in neim eigenen thread ablaufen lassen??



  • eigener thread da Messageloop ja auch wieder eine funktion ist die erst abgearbeitet werden muss und die in einer schleife bremmst ja auch wieder die abarbeitung der schleife oder??



  • Hm. Wenn du sicherstellen kannst dass nix "böses" passiert (d.h. alle Controls disabled sind etc.) dann keinen eigenen Thread.
    Muss dir halt nur klar sein dass sobald du nen Message Loop fährst von der Stelle dann auch weitere Handler aufgerufen werden können - also z.B. ein Handler für nen Button, oder OnClose oder sonstwas.

    Thread nur wenn nötig würde ich auch jeden Fall sagen.



  • Naja in der Schleife werden rechnungsschritte ausgeführt!

    1. Will daten der Berechung in ner Listbox anzeigen
    2. Will ich die schleife mit nem "Abbruch" Button Abbrechen

    deswegen sollte ich ja die MEssage loop aufrufen...

    bisher sieht man die DAten in er Listbox auch nicht in Echtzeit.. erst wenn die
    BErechunng fertig ist , werden die daten angezeigt!!


  • Mod

    Dieser Artikel zeigt Dir zwei gute Ansätze:
    http://www.microsoft.com/msj/0798/c0798.aspx



  • eine schleife ohne thread friert ja dein dialogfeld ein (kannst es nicht bewegen, nimmt keine buttonklicks mehr an usw...), jetzt könnte ich mir vorstellen das dies hier genau so passiert, selbst wenn du die Messageloop einbaust. was spricht gegen den thread wenn der sich beendet sobald die schleife zu ende ist.
    erstell dir ne membervariable typ bool beim start des threads ist die True und setzt die beim buttonklick auf False bzw. wenn die bedingungen der schleife deine berechnungen erfüllt sind.

    BOOL bTorF = TRUE;
    do
    {
    
    }while(bTorF);
    


  • LowFly schrieb:

    erstell dir ne membervariable typ bool beim start des threads ist die True und setzt die beim buttonklick auf False bzw. wenn die bedingungen der schleife deine berechnungen erfüllt sind.

    Ergänzung: Eine "nackte" Variable würde ich nicht für Thread-übergreifende Synchronisation verwenden - da solltest du zumindest die Zugriffe darauf unter Kontrolle bekommen. Oder du nimmst gleich einen Event, um dem Thread mitzuteilen, daß er beendet werden soll.

    @Hustbaer: Dann lieber alle Controls außer dem "Abbrechen"-Button disablen - das ist einfacher als wenn du die Message-Loop von Hand auseinandernehmen mußt.



  • hmm ok... würd ich das mit nem thread oder mit der message loop aufruf prinzip machen, kann man dann nich dafür sorgen das das dialog keine Move,Size oder close (das X oben rechts) Ereignisse annimmt?? sonder nur den Abrruch button?



  • Andere Dialogelemente kannst du einfach per EnableWindow(FALSE) ausschalten, dann nehmen sie keine Nachrichten mehr entgegen, für Systemnachrichten mußt du die entsprechenden Handler-Funktionen überschreiben und abschalten.

    Wobei: OnMove und OnSize abzuschalten dürfte sich nicht lohnen - und OnClose() würde ich so umbauen, daß es erst eine IDABORT schickt (um die Berechnung abzubrechen) und anschließend das Fenster schließt.



  • meine idee

    - ein "Bitte Warten" dialog welchen du modal aufrufst, so hast du schon das hauptfenster "deaktiviert"
    - in diesem dialog startest du das fuellen in einem eigenen thread
    - eine progressbar(optional) und ein abbrechen in diesen dialog
    - dieser dialog zerstoert sich selber sobald das thread zu ende ist
    - der abbrechen button beendet dann den thread - leert die liste und zerstoert das dialog fenster



  • @MrEvil: ja die Idee ist gar nich schlecht, allerding hab ich probleme mit threads , weis gar nich wie ich da anfagen soll.. gibts da kein Beispiel Code?



  • jo gibt es kuck mal da rein
    Pause Thread letzte post beschreibt wie du dir nen thread erstellst.


  • Mod

    Ich wiederhole mich:
    Dieser Artikel zeigt Dir zwei gute Ansätze:
    http://www.microsoft.com/msj/0798/c0798.aspx



  • sorry.. Martin hab ich irgendwie übersehen..ist ein gute Artikel und das buch von Paul Dilasica Windwos++ hab ich sogar:)



  • Jo, cooler Artikel.

    Artikel schrieb:

    It's true that threads are intimidating; multithreaded apps often exhibit complex behavior, including some very hard-to-find, hard-to-fix bugs. Multithreaded programs also often behave differently on multiprocessor machines, so you must always test them on both types. I usually steer people away from multithreading. Too often I see programmers using threads just to prove how smart they are, when the really smart thing would be to redesign your program slightly to avoid threads entirely.

    Genau deswegen bin ich gegen die "Thread-Lösung" 🙂

    @CStoll:
    Jo, irgendwie sicher stellen dass kein Scheiss passieren kann. Alle Controls bis auf "Abbrechen" disablen und "OnCancel" überschreiben ist schonmal gut. Und der "Abbrechen" Handler sowie das überschriebene "OnCancel" machen dann im Prinzip bloss ein "m_killFlag = true;", woraufhin die "Sachen mach Schleife" dann eben abbricht.



  • jepp.. Mein Arbeitgeber ist auch hardcore Progger, und der verzichte auch auf Trhead wenns nur irgendwie geht, auch wenn Lösungen mit threads eleganter und kürzer erscheinen sollte man sich nicht verleiten lassen.. 🙂 also lieber message loop aurufen;)



  • Ich bin für die Threadlösung.

    Dadurch kannst Du ohne viel Overhead die Oberfläche von aufwändigen Berechnungen trennen.

    Die Implementierung ist mit der MFC auch nicht sehr schwer:

    1.)Definiere dir eine Threadfunktion, die die Berechnung durchführt:

    UINT MyControllingFunction( LPVOID pParam );

    2.) Rufe den Thread an geeigneter Stelle auf

    AfxBeginThread(MyControllingFunction, pParam);

    - Daten auf denen der Thread rechnen soll übergibst Du als pParam
    - Wenn der Thread zusätzlich das Ende seiner Berechnung an den Hauptthread melden soll, kannst Du dies durch das Senden einer Nachricht machen, deren Message-Handler Du dann auch implementieren musst.


  • Mod

    Ich tendiere auch eher zu multithreading Lösungen.
    Das sah früher etwas anders aus, aber heute sehe ich es oft genug als einfachere und besser gekapselte Lösung an.

    Wenn man sich klar ist was der Thread manipuliert bzw. was ausgetauscht wird ist es wirklich bei weitem oft die einfachere Lösung. Wenn man dann das ganze noch in seine eigene UI mit ein paar Klassen einbindet und kapselt dann gibt es nicht leichteres.

    Es muss einem klar sein, dass man gar keine anderen Chancen hat als multithreading, wenn noch andere Komponenten oder Datenbank Abfragen mit asynchronem Verhalten dazukommen. Ehe ich dann zwei Ansätze verwende, dann lieber gleich multithreading.
    Aber das ist eben Geschmackssache. :xmas1:

    BTW: Deswegen finde ich den Artikel so gut, er behandelt beide Ansätze!


Log in to reply