2009-02-03 4 views
9

Ich habe Probleme mit etwas, was ich tun möchte. Ich habe einige große Formulare, die einige Zeit brauchen. Um die App schneller laden zu können, habe ich mir gedacht, die Formulare in einem Thread erstellen zu lassen, der beim OnCreate-Ereignis des Hauptformulars erstellt wird. Der Thread hat ein FApplication-Feld vom Typ TApplication, das offensichtlich die Application-Variable ist. Ich benutze dass die Formulare auf den Faden zu schaffen, aber auch tho Ich habe versucht,Delphi-Formularerstellung ohne Einfrieren des Hauptthreads

FApplication.CreateForm (TfrmXXX, frmXXX) 

und

frmXXX := TFrmXXX.Create(FApplication) 

die Formen noch erstellt Arent. Gibt es einen Workaround dafür?

Vielen Dank im Voraus.

Antwort

26

Erstellen von Formularen in einem Thread wird einfach nicht funktionieren. Die VCL und insbesondere der visuelle Teil ist nicht Thread-sicher. Geben Sie diese Idee auf und optimieren Sie stattdessen den Code, der die Erstellung des Formulars lange Zeit in Anspruch nimmt. Du hast uns nicht gesagt, was der langsame Teil ist. Wenn Sie das beantworten können, können wir vielleicht eine Methode vorschlagen, um es zu beschleunigen.

Im Allgemeinen ist es nicht möglich, die Leistung eines Codeabschnitts zu verbessern, bis Sie ein Profil erstellt haben und genau wissen, wo das Problem liegt. Ansonsten verschwendest du nur deine Zeit.

+1

Eigentlich in einem Gewinde unterscheidet sich von dem Haupt-UI-Thread ein Fenster zu schaffen ist eine völlig legitime Idee in Win32, das seinen Gebrauch hat. Dies hat nichts damit zu tun, dass VCL Thread-sicher ist. Wenn ich 3 Threads mit jeweils einer eigenen Nachrichtenschleife haben möchte, warum würde VCL das interessieren? Die Nachrichtenschleifen sollten nicht miteinander kommunizieren, sie befinden sich in getrennten Kontexten (d. H. Kein Problem mit der Thread-Sicherheit). –

+2

Milan, Win32-Fenster <> VCL-Formular. Er möchte eine VCL-Form haben, und das kannst du einfach nicht tun, egal wie kurz du willst. –

6

Die Lösung wird nicht einfach sein, wie

  1. die Delphi VCL nicht sicher
  2. Schaffung Fenster in einem anderen Thread ist Thread benötigt den jeweiligen Thread eine Nachrichtenschleife
haben

Benötigen Sie alle Formulare gleichzeitig? Wenn nicht, könnten Sie die Erstellung auf einen Zeitpunkt verschieben, an dem die Anwendung inaktiv ist (d. H. TApplicationEvents.OnIdle). Oder zeige einfach einen schönen Fortschrittsbalken an :)

+0

Ich habe diese Antwort für den Hinweis, dass Sie nicht alle Formulare auf einmal erstellen müssen, gewählt, aber eine Fortschrittsleiste würde mich als Benutzer an die Wand fahren. :) –

+1

Ja, im Grunde fühle ich das gleiche. Aber wenn es unvermeidbar ist, langwierige Operationen beim Start zu machen, ist es besser, eine als nicht zu haben. Ich habe einmal vergessen, eines zu zeigen, und die Kunden haben die App beendet, weil sie gedacht haben, dass sie hängt: -/Aber wie auch immer - Sie haben sicherlich recht, wenn Sie weitere Optimierungen vorschlagen. –

0

Ich kann mir nicht vorstellen, was bei der Formularerstellung so lange dauern würde, dass Threads aufgelöst werden müssten. Wenn es sich um eine große Datenmenge handelt, versuchen Sie, die anfänglich angezeigte Menge zu begrenzen.

4

Wie Riho betont, sollte die Formularerstellung keine Zeit in Anspruch nehmen. Was jedoch Zeit in Anspruch nehmen kann, ist der gesamte Code, den Sie in den Konstruktor oder das OnCreate-Ereignis dieses Formulars schreiben.

Profilieren Sie Ihren Code, wie Craig vorgeschlagen hat, damit Sie wissen, welcher Code die meiste Zeit beansprucht. Dann sehen Sie, ob Sie etwas von diesem Code in einen separaten Thread verschieben können.

0

Dies ist eine Abkürzung, die wir schon früher für Formulare verwendet haben, die viel zu erstellen haben. Legen Sie einen TTimer auf das Formular und legen Sie es auf false fest. OnCreate des Formulars aktivieren Sie es. Dann fügen Sie den gesamten Code, den Sie in OnCreate hatten, in das OnTimer Event ein. Das Intervall auf 250 bis 500 zu setzen ist ausreichend.

Dies ist keine elegante Lösung, aber es ist einfach.

0

Es gibt einige große Formen da draußen, wie ich bereits sagte. Die DFM-Datei ist wie 3 MB (einschließlich der Bilddaten natürlich). Ich denke eigentlich, dass der Großteil der Erstellungszeit eher auf den Code als auf den Code zurückzuführen ist. Aber vielleicht schlecht Split em und erstellen sie, wenn App im Leerlauf ist, ist die aktuelle Ladezeit nicht wirklich groß (wie 4 oder 5 Sekunden), aber schlecht hineinschauen. Danke für deine Antworten.

1

Wie oben müssen Sie die Formulare im VCL-Thread erstellen. ABER, brauchen Sie nicht alles, was es zu tun:

Wenn Ihre Formulare viele Bilddaten haben, könnten Sie das entfernen von den Formen, und legen Sie sie in einer Ressourcendatei (oder nur RAW-Bilddateien verwenden)

Starten Sie im Konstruktor Ihres Formulars einen Hintergrund-Thread, um die Bilddaten von Ressourcen zu lesen und andere langsame Dinge zu tun. Überschreiben Sie das OnShow-Ereignis für Formulare, um sicherzustellen, dass es auf den Abschluss des Hintergrundthreads wartet, bevor das Formular angezeigt wird.

1

Fügen Sie einfach eine PostMessage in die Formulare OnCreate ein und führen Sie eine Prozedur auf dem Formular aus, um die Postnachricht zu bearbeiten. Auf diese Weise kann der gesamte Code, der Zeit benötigt, aus der OnCreate-Methode entfernt werden. Ich stimme jedoch zu, nur das Formular erstellen, wenn es benötigt wird, und dann tatsächlich implementieren einige Logik zu entscheiden, ob Sie es bei Abschluss zu befreien, oder nicht .. Je nach Ladezeit und Chance, dass der Benutzer es wieder wollen wird ..

Jens Fudge, Archersoft

Verwandte Themen