0

I'm using a Splash Screen from Here. I love how simple it is. But the problem with it is that the splash screen doesn't go away until I click on it. When run within the IDE it works fine. Any ideas? I'd attach the code here but its not inserting properly for some reason.

private System.Windows.Forms.Timer timer1;
//private Splash sp=null;

public Form1()
{
    InitializeComponent();

    Thread th = new Thread(new ThreadStart(DoSplash));
    //th.ApartmentState = ApartmentState.STA;
    //th.IsBackground=true;
    th.Start();
    Thread.Sleep(3000);
    th.Abort();
    Thread.Sleep(1000);
}

private void DoSplash()
{
    Splash sp = new Splash();
    sp.ShowDialog();
}

private void timer1_Tick(object sender, System.EventArgs e)
{
//      sp.Close();
}
JimDel
  • 4,309
  • 11
  • 54
  • 99
  • ...thanks for adding the code. Not sure why I had so much trouble with it formatting properly. – JimDel Jun 01 '09 at 22:57

3 Answers3

6

First of all, the way the splash screen on that page is done, using Thread.Abort, is not the right way to do things.

Never call Thread.Abort, unless you're in the process of shutting down the AppDomain the thread lives in.

Let me reiterate that for emphasis. The only time you should call Thread.Abort is when you know enough about Thread.Abort and how it behaves to know that you should never call it.

Take a look at this other question on StackOverflow: Multi-Threaded splash screen in c#?.


If you want to keep your existing solution, a possible better way would be to drop a timer into the splash screen form, set its timer to the time you want the splash screen to stay on screen, and call Close in its Tick event handler.

In the same venue, I would simply fire off that original thread, and remove the other lines.

In other words, from the first code block on that page, I would keep these two lines:

Thread th = new Thread(new ThreadStart(DoSplash));
th.Start();

Couple that with that timer on the form that makes the form self-closing, and you're in way better shape than trying to get to grips with Thread.Abort.

Which you should not call.

Community
  • 1
  • 1
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • "The only time you should call..." Well put. – Michael Petrotta Jun 01 '09 at 22:36
  • I like the idea of using the "OnCreateSplashScreen" method because it seems to be the preferred way of doing it I see. But as a beginner there isn't a lot of explanation there to get me going. However, the answer given by "aku" on that same page you referenced did the trick for me. Thank you for pointing me in the right direction. – JimDel Jun 01 '09 at 23:32
  • Just found a nice site with a step by step for using the VB method. http://www.softwarepassion.com/?p=152 – JimDel Jun 02 '09 at 00:47
2

The DoSplash should probably call sp.Show() instead of sp.ShowDialog()

But calling Sleep(x000) form your main thread to show a splash screen isn't very efficient, and Thread.Abort() should be reserved for better use too.

A better approach is to close your SplashForm with a Timer and set a minimum delay. On startup you can Show() and Update() the SplahForm and continue to load stuff. The timer event won't fire until the MainForm is finished initializing and enters the EventLoop. No threads needed, and the MainForm doesn't have to be involved either.

Just to give you the main ingredients of a MessageLoop driven SplashForm:

public partial class SplashForm : Form
{
    //  default stuff

    public static void Splash()
    {
        var s = new SplashForm();
        s.Show();
        s.Update();// force paint
    }

    private void SplashForm_Load(object sender, EventArgs e)
    {
        Timer t = new Timer();
        t.Interval = 1; // wait for EventLoop
        t.Tick += GoAway;
        t.Enabled = true;
    }

    private void GoAway(object sender, EventArgs e)
    {
        this.Close();
    }
}

and then, in Program.cs,

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SplashForm.Splash();
Application.Run(new MainForm());
H H
  • 263,252
  • 30
  • 330
  • 514
  • No, that would just give him another problem, that the splash screen wouldn't stay on screen. ShowDialog doesn't return until the form has been closed, but .Show does, and thus the thread ends abruptly because there is no message loop running. – Lasse V. Karlsen Jun 01 '09 at 22:32
  • @Lasse, you're probably right, i stopped reading the linked sample rather quickly. Nice picture though. – H H Jun 01 '09 at 22:37
  • Yeah, I liked that as well. Yin and ... err... Windows. (on second thought, looks like he removed Yin, so that's Yang and Windows. – Lasse V. Karlsen Jun 01 '09 at 22:41
1

That's an ugly implementation. You should check out this SO thread. That describes how to use the VisualBasic.NET namespace from C# and the OnCreateSplashScreen method to do a much cleaner splash screen implementation.

Community
  • 1
  • 1
JP Alioto
  • 44,864
  • 6
  • 88
  • 112
  • Thanks for the link to the info on the OnCreateSpashScreen method. I'll have to do some looking into that. – JimDel Jun 01 '09 at 23:33