Announcement

Collapse
No announcement yet.

Application.ProcessMessages performance-relevant?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Application.ProcessMessages performance-relevant?

    Ich schreibe z.Z. an einer Dateisystem-Rekursion, während der ich Application.ProcessMessages unterbringe aus bekannten Gründen. Nun stellt sich mir jedoch die Frage, ob die Performance leiden kann, wenn ich bei jedem Scanschritt (eine Datei/Verz. weiter) den Befehl aufrufe. Bzw. ist es sinnvoll nur alle - was weiß ich - 128 Durchläufe Application.ProcessMessages ausführen zu lassen?

  • #2
    Hallo Dirk,

    es ist auf jeden Fall sinnvoll nich nach jeder gefundenen Datei "Application.ProcessMessages" aufzurufen.

    Gruß

    Torste

    Comment


    • #3
      Das ist natuerlich performance-relevant. Du erlaubst deinem Programm Messages abzuarbeiten und damit kann es fast beliebig lange dauern bis es weitergeht.<br>
      Es bietet sich an die Taetigkeit in einen Thread zu verlagern. ProcessMessages zu benutzen ist fast immer ein Fehler. Meist bringen di Programmierer damit das Programm in einen unrunden Zustand

      Comment


      • #4
        Hallo,

        ein zusätzlicher Thread würde an der Leistungsbilanz nichts ändern, solange nur eine einzige CPU im Rechner steckt. Die Sache ist doch die:

        1. Eine Anwendung, deren Oberfläche nicht "einfrieren" soll und bei der im Task-Manager nicht die Status-Anzeige "Anwendung reagiert nicht" erscheinen soll, muss die eigene Botschaftwarteschlange in regelmässigen kurzen Abständen auslesen und die dort vorgefundenen Windows-Botschaften abarbeiten. Der primäre Thread der Anwendung würde also in jedem Fall die Rechenzeit "verbraten", die Rechenzeit eines eventuell abgespalteten Threads käme dann noch hinzu.

        2. Solange beim ProcessMessages-Aufruf neue (unabearbeiteten) Botschaften in der Warteschlange vorgefunden werden, muss die Anwendung diese abarbeiten, damit es nicht zu dem unter 1. beschriebenen negativen Verhalten kommt.

        3. Nur dann, wenn es toleriert wird, dass der Anwender über eine längere Zeit keine aktualisierte Benutzeroberfläche (Beispiel: Fenster wird verschoben und stellt sich dann "beschädigt" dar) zu Gesicht bekommt, darf man aus Performance-Überlegungen auf das regelmässige Auslesen der Botschaftswarteschlage aus dem primären Thread heraus verzichten (es sein denn, das Programm greift auf COM-Funktionen zurück)

        Comment


        • #5
          Der Nachteil von ProcessMessages ist das es schwer zu findende Probleme in die Programmlogik einschleust.<br>
          Paradebeispiel ist das Aufrufen von ProcessMessages in einem OnClick der laengere Zeit vor sich hinprozessiert. Jetzt kann man das Programm schliessen und wundert sich warum nichts passiert.<br>
          Wenn man nun sein Programm ausf diese Vorgehensweise abstimmt, dann bekommt man ein haessliches schwer wartbares Programm

          Comment


          • #6
            Hallo Robert,

            ich weiß das Posting ist schon älter, ich bin aber gerade erst darüber gestolpert (bin nicht so oft im Delphibereich ).

            Ich fürchte Du bist da einem Denkfehler aufgesessen. Man nutzt ProcessMessages() doch <I>gerade</I> in länger dauernden Funktionen - und zu 99% werden diese durch eine Benutzeraktion ausgelöst (OnClick). Natürlich passiert nichts, wenn man nicht auf die Abbruchaufforderung reagiert. Dieses kann man in einer überschriebenen WndProc() realisieren. Notfalls kann man in der OnCloseQuery() einfach eine Meldung ausgeben, daß das Programm zur Zeit nicht geschlossen werden kann. Besser wäre es eine globale Variable zu verwenden, deren Wert von Zeit zu Zeit in den Schleifen abgefragt wird.

            Einfaches Beispiel (bin zu faul zu versuchen, das nach Pascal umzusetzen, sollte aber auch so verständlich sein):
            Man nehme: Ein Form mit einem Button und einem Label. Man definiere eine globale Variable Abort, Typ bool, initialisiert mit false. <BR>
            OnClick des Buttons:
            <PRE>
            void __fastcall TForm1::Button1Click(TObject *Sender)
            {
            for (int i = 0; i < 100000; i++)
            {
            if (Abort)
            break;
            for (int j = 0; j < 100000; j++)
            Label1->Caption = AnsiString(i);
            Application->ProcessMessages();
            }
            }
            </PRE>
            Ereignis OnCloseQuery():
            <PRE>
            void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
            {
            if (Application->MessageBoxA("Beenden?", "Beenden", MB_YESNO) == IDYES)
            {
            CanClose = true;
            Abort = true;
            }
            else
            CanClose = false;
            }
            </PRE>
            Und siehe da, wenn Du 'Ja' anklickst wird das Programm sofort geschlossen...

            Grüße Joche

            Comment

            Working...
            X