none
Splashscreen - Zwei Nachrichtenschleifen?

    Frage

  • Hi,

    vor dem Öffnen meines Hauptfensters möchte ich ein paar Dateien kopieren und währenddessen einen Splashscreen anzeigen. Das Kopieren soll im Hintergrund passieren, damit die Anwendung nicht blockiert und der Benutzer zwischen dieser und anderen Anwednungen hin- und herwechseln kann. Ist die folgende Lösung ok, oder würdet ihr das ganz anders umsetzen. Mich beunruhigt dabei, dass ich zweimal Application.Run() aufrufe, also zwei Nachrichtenschleifen starte.

        static class Program
        {
            /// <summary>
            /// Der Haupteinstiegspunkt für die Anwendung.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
    
                Splash splash = new Splash();
                splash.Show();
                Task.Factory.StartNew(() =>
                {
                    System.Threading.Thread.Sleep(3000); // Simuliert Kopierarbeit.
                    splash.Invoke(new MethodInvoker(() => { splash.Close(); }));
                    Application.Run(new Form1());
                });
                Application.Run();
            }
        }

    Wenn ich statt

    Application.Run(new Form1());

    nur

    (new Form1()).Show();
    verwende, ist Form1 nicht bedienbar (blockiert).

    LG;-)

    • Bearbeitet free.runn3r Sonntag, 8. September 2013 21:03
    Sonntag, 8. September 2013 20:52

Antworten

  • Hallo,
    ich würde das ganze etwas anders umsetzen. Ich würde in der Splash-Screen-Form in einem Backgroundworker (o.ä.) die Kopierarbeit machen lassen. Den Backgroundworker dafür am besten im Load-Event starten.
    Wenn der BW nun fertig ist, dann schließt er einfach die Form.

    Aufrufen kannst du den Splashscreen am Anfang des Form-Konstruktors. Die Form ist zu diesem Zeitpunkt nichtmal ansatzweise geladen. Die Program.cs kannst du dabei komplett in Ruhe lassen.

        public partial class Form1 : Form
        {
            public Form1()
            {
                Splashscreen ss = new Splashscreen();
                ss.ShowDialog();
                InitializeComponent();
            }
        }
        public partial class Splashscreen : Form
        {
            public Splashscreen()
            {
                InitializeComponent();
            }
    
            private void Splashscreen_Load(object sender, EventArgs e)
            {
                backgroundWorker1.RunWorkerAsync();
            }
    
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                Thread.Sleep(3000);//Kopierarbeit
    
            }
    
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                this.Close();
            }
        }

    So würde ich es machen.

    Grundsätzlich könntest du auch einfach beide Forms in Main() erzeugen und nacheinander anzeigen. Also ohne Application.Run(). Dabei gibt es aber ein paar Dinge zu beachten.
    Einen doppelten Aufruf von Application.Run würde ich versuchen zu vermeiden.




    <Code-13/>- Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    • Als Antwort markiert free.runn3r Sonntag, 8. September 2013 21:37
    Sonntag, 8. September 2013 21:09

Alle Antworten

  • Hallo,
    ich würde das ganze etwas anders umsetzen. Ich würde in der Splash-Screen-Form in einem Backgroundworker (o.ä.) die Kopierarbeit machen lassen. Den Backgroundworker dafür am besten im Load-Event starten.
    Wenn der BW nun fertig ist, dann schließt er einfach die Form.

    Aufrufen kannst du den Splashscreen am Anfang des Form-Konstruktors. Die Form ist zu diesem Zeitpunkt nichtmal ansatzweise geladen. Die Program.cs kannst du dabei komplett in Ruhe lassen.

        public partial class Form1 : Form
        {
            public Form1()
            {
                Splashscreen ss = new Splashscreen();
                ss.ShowDialog();
                InitializeComponent();
            }
        }
        public partial class Splashscreen : Form
        {
            public Splashscreen()
            {
                InitializeComponent();
            }
    
            private void Splashscreen_Load(object sender, EventArgs e)
            {
                backgroundWorker1.RunWorkerAsync();
            }
    
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                Thread.Sleep(3000);//Kopierarbeit
    
            }
    
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                this.Close();
            }
        }

    So würde ich es machen.

    Grundsätzlich könntest du auch einfach beide Forms in Main() erzeugen und nacheinander anzeigen. Also ohne Application.Run(). Dabei gibt es aber ein paar Dinge zu beachten.
    Einen doppelten Aufruf von Application.Run würde ich versuchen zu vermeiden.




    <Code-13/>- Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    • Als Antwort markiert free.runn3r Sonntag, 8. September 2013 21:37
    Sonntag, 8. September 2013 21:09
  • Hey,

    so hatte ich es zuerst versucht, aber immer wurden Splashscreen und Hauptform gleichzeitig geladen.

    ShowDialog();

    ist der Schlüssel.

    Vielen Dank.

    LG;-)


    • Bearbeitet free.runn3r Sonntag, 8. September 2013 21:40
    Sonntag, 8. September 2013 21:39