1

So I have a splash screen which will have some time intensive code and I don't want it running in the main thread. I have made some code which should stop the thread and close the form, but it does not work. Any help is welcomed.

Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace Cobalt
{
    partial class Cobalt : Form
    {
        public static bool splashCont { get; set; }

        public Cobalt()
        {
            this.Text = "Cobalt V1.0.0";
            this.Width = 400;
            this.Height = 100;
            this.BackgroundImage = Properties.Resources.cobaltlgo;
            this.FormBorderStyle = FormBorderStyle.None;
            this.TopMost = true;
            this.StartPosition = FormStartPosition.CenterScreen;

            Thread splash = new Thread(new ThreadStart(splashLoadAction));
            splash.Start();

            if (splashCont)
            {
                splash.Abort();

                this.Close();
            }
        }

        private void splashLoadAction()
        {
            Thread.Sleep(5000);
            Cobalt.splashCont = true;
        }
    }
}

The program just stays at this screen: Screen EDIT: I was able to fix this by using the following code:

Invoke((MethodInvoker)delegate { MyNextForm.Show(); });

Which invokes MyNextForm.Show() on the UI thread.

steve
  • 107
  • 10

3 Answers3

0

If you want the work being done in the splash screen form, you can simplify this greatly. This assumes that your five-second sleep is simulating the startup work being done. This way the splash form will simply close itself out when the startup work is done.

partial class Cobalt : Form
{
    public Cobalt()
    {
        this.Text = "Cobalt V1.0.0";
        this.Width = 400;
        this.Height = 100;
        this.BackgroundImage = Properties.Resources.cobaltlgo;
        this.FormBorderStyle = FormBorderStyle.None;
        this.TopMost = true;
        this.StartPosition = FormStartPosition.CenterScreen;
        this.Show();
        splashLoadAction();
        this.Close();
    }

    private void splashLoadAction()
    {
        Thread.Sleep(5000);
    }
}
Murray Hertz
  • 112
  • 1
  • 5
0

You should put a timer in your splash screen form and close it once the time has been elapsed. You probably want to modify your application entry point so that this form is displayed before you start the main application form.

Well, in real life application, it might be more complicate than this if you want for example keep the splash displayed longer if the application is not ready or until the main form is actually displayed.

That might be useful if it take time to display the main application windows as having no windows displayed during a few second between the time the splash is closed and the application is visible might make your user think that the application has crashed...

Using timer, idle and visibility events, you can do anything you want exactly like you want once you understand how everything works.

Phil1970
  • 2,605
  • 2
  • 14
  • 15
-1

As you have thread.sleep in the thread, the main thread will continue executing so the code

if (splashCont)
{
    splash.Abort();

    this.Close();
}

will execute well before you could set the splashCnt = true.

Check if you really need to sleep the thread, if required then needs to think of workaround for it.

if you really want the thread to sleep than you could make the main thread wait for the sub thread to complete

while (splash.IsAlive)
{
    Thread.Sleep(1000);
}

if (splashCont)
{
    splash.Abort();
    this.Close();
}
Mallappa
  • 1
  • 3
  • But then the main thread is stopped and the GUI does not appear – steve Nov 10 '16 at 04:05
  • If you don't want to put the Thread.Sleep in the mean thread then you might have to take of Thread.Sleep from the method which is being called from thread also. – Mallappa Nov 10 '16 at 04:51