<p>I want a splash screen to show while the application is loading. I have a form with a system tray control tied to it. I want the splash screen to display while this form loads, which takes a bit of time since it's accessing a web service API to populate some drop-downs. I also want to do some basic testing for dependencies before loading (that is, the web service is available, the configuration file is readable).  As each phase of the startup goes, I want to update the splash screen with progress.</p>

<p>I have been reading a lot on threading, but I am getting lost on where this should be controlled from (the <code>main()</code> method?). I am also missing how <code>Application.Run()</code> works, is this where the threads for this should be created from? Now, if the form with the system tray control is the "living" form, should the splash come from there? Wouldn't it not load until the form is completed anyway?</p>

<p>I'm not looking for a code handout, more of an algorithm/approach so I can figure this out once and for all :) </p>

[{'answer_id': 48944, 'author': 'McKenzieG1', 'author_id': 3776, 'author_profile': 'https://Stackoverflow.com/users/3776', 'pm_score': 3, 'selected': False, 'text': '<p>One simple way is the use something like this as main():</p>\n\n<pre><code>&lt;STAThread()&gt; Public Shared Sub Main()\n\n    splash = New frmSplash\n    splash.Show()\n\n    \' Your startup code goes here...\n\n    UpdateSplashAndLogMessage("Startup part 1 done...")\n\n    \' ... and more as needed...\n\n    splash.Hide()\n    Application.Run(myMainForm)\nEnd Sub\n</code></pre>\n\n<p>When the .NET CLR starts your application, it creates a \'main\' thread and starts executing your main() on that thread. The Application.Run(myMainForm) at the end does two things:</p>\n\n<ol>\n<li>Starts the Windows \'message pump\', using the thread that has been executing main() as the GUI thread.</li>\n<li>Designates your \'main form\' as the \'shutdown form\' for the application. If the user closes that form, then the Application.Run() terminates and control returns to your main(), where you can do any shutdown you want.</li>\n</ol>\n\n<p>There is no need to spawn a thread to take care of the splash window, and in fact this is a bad idea, because then you would have to use thread-safe techniques to update the splash contents from main().</p>\n\n<p>If you need other threads to do background operations in your application, you can spawn them from main(). Just remember to set Thread.IsBackground to True, so that they will die when the main / GUI thread terminates. Otherwise you will have to arrange to terminate all your other threads yourself, or they will keep your application alive (but with no GUI) when the main thread terminates.</p>\n'}, {'answer_id': 48946, 'author': 'aku', 'author_id': 1196, 'author_profile': 'https://Stackoverflow.com/users/1196', 'pm_score': 6, 'selected': False, 'text': '<p>The trick is to to create separate thread responsible for splash screen showing.<br>\nWhen you run you app .net creates main thread and loads specified (main) form. To conceal hard work you can hide main form until loading is done. </p>\n\n<p>Assuming that Form1 - is your main form and SplashForm is top level, borderles nice splash form:</p>\n\n<pre><code>private void Form1_Load(object sender, EventArgs e)\n{\n    Hide();\n    bool done = false;\n    ThreadPool.QueueUserWorkItem((x) =&gt;\n    {\n        using (var splashForm = new SplashForm())\n        {\n            splashForm.Show();\n            while (!done)\n                Application.DoEvents();\n            splashForm.Close();\n        }\n    });\n\n    Thread.Sleep(3000); // Emulate hardwork\n    done = true;\n    Show();\n}\n</code></pre>\n'}, {'answer_id': 48971, 'author': 'Guy Starbuck', 'author_id': 2194, 'author_profile': 'https://Stackoverflow.com/users/2194', 'pm_score': 7, 'selected': True, 'text': '<p>Well, for a ClickOnce app that I deployed in the past, we used the <code>Microsoft.VisualBasic</code> namespace to handle the splash screen threading.  You can reference and use the <code>Microsoft.VisualBasic</code> assembly from C# in .NET 2.0 and it provides a lot of nice services.</p>\n\n<ol>\n<li>Have the main form inherit from <code>Microsoft.VisualBasic.WindowsFormsApplicationBase</code></li>\n<li><p>Override the "OnCreateSplashScreen" method like so:</p>\n\n<pre><code>protected override void OnCreateSplashScreen()\n{\n    this.SplashScreen = new SplashForm();\n    this.SplashScreen.TopMost = true;\n}\n</code></pre></li>\n</ol>\n\n<p>Very straightforward, it shows your SplashForm (which you need to create) while loading is going on, then closes it automatically once the main form has completed loading.</p>\n\n<p>This really makes things simple, and the <code>VisualBasic.WindowsFormsApplicationBase</code> is of course well tested by Microsoft and has a lot of functionality that can make your life a lot easier in Winforms, even in an application that is 100% C#.</p>\n\n<p>At the end of the day, it\'s all IL and <code>bytecode</code> anyway, so why not use it?</p>\n'}, {'answer_id': 49031, 'author': 'Peter Meyer', 'author_id': 1875, 'author_profile': 'https://Stackoverflow.com/users/1875', 'pm_score': 3, 'selected': False, 'text': '<p>I think using some method like <a href="https://stackoverflow.com/questions/48916/multi-threaded-splash-screen-in-c#48946">aku\'s</a> or <a href="https://stackoverflow.com/questions/48916/multi-threaded-splash-screen-in-c#48971">Guy\'s</a> is the way to go, but a couple of things to take away from the specific examples:</p>\n\n<ol>\n<li><p>The basic premise would be to show your splash on a separate thread as soon as possible.  That\'s the way I would lean, similar to what aku\'s illustrated, since it\'s the way I\'m most familiar with.  I was not aware of the VB function Guy mentioned.  And, even thought it\'s a <em>VB</em> library, he is right -- it\'s all IL in the end.  So, even if it feels <em>dirty</em> it\'s not all that bad!  :)  I think you\'ll want to be sure that either VB provides a separate thread for in that override or that you create one yourself -- definitely research that.</p></li>\n<li><p>Assuming you create another thread to display this splash, you will want to be careful of cross thread UI updates.  I bring this up because you mentioned updating progress.  Basically, to be safe, you need to call an update function (that you create) on the splash form using a delegate.  You pass that delegate to the <a href="http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx" rel="nofollow noreferrer">Invoke</a> function on your splash screen\'s form object.  In fact if you call the splash form directly to update progress/UI elements on it, you\'ll get an exception provided you are running on the .Net 2.0 CLR.  As a rule of thumb, any UI element on a form must be updated by the thread that created it -- that\'s what Form.Invoke insures.</p></li>\n</ol>\n\n<p>Finally, I would likely opt to create the splash (if not using the VB overload) in the main method of your code.  To me this is better than having the main form perform creation of the object and to be so tightly bound to it.  If you take that approach, I\'d suggest creating a simple interface that the splash screen implements -- something like IStartupProgressListener -- which receives start-up progress updates via a member function.  This will allow you to easily swap in/out either class as needed, and nicely decouples the code.  The splash form can also know when to close itself if you notify when start-up is complete.</p>\n'}, {'answer_id': 2117094, 'author': 'DelftRed', 'author_id': 256697, 'author_profile': 'https://Stackoverflow.com/users/256697', 'pm_score': 3, 'selected': False, 'text': "<p>I recommend calling <code>Activate();</code> directly after the last <code>Show();</code> in the answer provided by aku.</p>\n\n<p>Quoting MSDN: </p>\n\n<blockquote>\n  <p>Activating a form brings it to the\n  front if this is the active\n  application, or it flashes the window\n  caption if this is not the active\n  application. The form must be visible\n  for this method to have any effect.</p>\n</blockquote>\n\n<p>If you don't activate your main form, it may be displayed <em>behind</em> any other open windows, making it look a bit silly.</p>\n"}, {'answer_id': 2117218, 'author': 'K Singh', 'author_id': 139406, 'author_profile': 'https://Stackoverflow.com/users/139406', 'pm_score': 2, 'selected': False, 'text': '<p>I posted an article on splash screen incorporation in the application at codeproject. It is multithreaded and might be of your interest</p>\n\n<p><a href="http://www.codeproject.com/KB/dotnet/Yet_Another_Splash_Screen.aspx" rel="noreferrer">Yet Another Splash Screen in C#</a></p>\n'}, {'answer_id': 3296362, 'author': 'Jay', 'author_id': 114994, 'author_profile': 'https://Stackoverflow.com/users/114994', 'pm_score': 3, 'selected': False, 'text': '<p>This is an old question, but I kept coming across it when trying to find a threaded splash screen solution for WPF that could include animation.</p>\n\n<p>Here is what I ultimately pieced together:</p>\n\n<p>App.XAML:</p>\n\n<pre><code>&lt;Application Startup="ApplicationStart" …\n</code></pre>\n\n<p>App.XAML.cs:</p>\n\n<pre><code>void ApplicationStart(object sender, StartupEventArgs e)\n{\n        var thread = new Thread(() =&gt;\n        {\n            Dispatcher.CurrentDispatcher.BeginInvoke ((Action)(() =&gt; new MySplashForm().Show()));\n            Dispatcher.Run();\n        });\n        thread.SetApartmentState(ApartmentState.STA);\n        thread.IsBackground = true;\n        thread.Start();\n\n        // call synchronous configuration process\n        // and declare/get reference to "main form"\n\n        thread.Abort();\n\n        mainForm.Show();\n        mainForm.Activate();\n  }\n</code></pre>\n'}, {'answer_id': 4994912, 'author': 'Adam Nofsinger', 'author_id': 18524, 'author_profile': 'https://Stackoverflow.com/users/18524', 'pm_score': 4, 'selected': False, 'text': '<p>After looking all over Google and SO for solutions, this is my favorite:\n<a href="http://bytes.com/topic/c-sharp/answers/277446-winform-startup-splash-screen">http://bytes.com/topic/c-sharp/answers/277446-winform-startup-splash-screen</a></p>\n\n<p><strong>FormSplash.cs:</strong></p>\n\n<pre><code>public partial class FormSplash : Form\n{\n    private static Thread _splashThread;\n    private static FormSplash _splashForm;\n\n    public FormSplash() {\n        InitializeComponent();\n    }\n\n    /// &lt;summary&gt;\n    /// Show the Splash Screen (Loading...)\n    /// &lt;/summary&gt;\n    public static void ShowSplash()\n    {\n        if (_splashThread == null)\n        {\n            // show the form in a new thread\n            _splashThread = new Thread(new ThreadStart(DoShowSplash));\n            _splashThread.IsBackground = true;\n            _splashThread.Start();\n        }\n    }\n\n    // called by the thread\n    private static void DoShowSplash()\n    {\n        if (_splashForm == null)\n            _splashForm = new FormSplash();\n\n        // create a new message pump on this thread (started from ShowSplash)\n        Application.Run(_splashForm);\n    }\n\n    /// &lt;summary&gt;\n    /// Close the splash (Loading...) screen\n    /// &lt;/summary&gt;\n    public static void CloseSplash()\n    {\n        // need to call on the thread that launched this splash\n        if (_splashForm.InvokeRequired)\n            _splashForm.Invoke(new MethodInvoker(CloseSplash));\n\n        else\n            Application.ExitThread();\n    }\n}\n</code></pre>\n\n<p><strong>Program.cs:</strong></p>\n\n<pre><code>static class Program\n{\n    /// &lt;summary&gt;\n    /// The main entry point for the application.\n    /// &lt;/summary&gt;\n    [STAThread]\n    static void Main(string[] args)\n    {\n        // splash screen, which is terminated in FormMain\n        FormSplash.ShowSplash();\n\n        Application.EnableVisualStyles();\n        Application.SetCompatibleTextRenderingDefault(false);\n        // this is probably where your heavy lifting is:\n        Application.Run(new FormMain());\n    }\n}\n</code></pre>\n\n<p><strong>FormMain.cs</strong></p>\n\n<pre><code>    ...\n\n    public FormMain()\n    {\n        InitializeComponent();            \n\n        // bunch of database access, form loading, etc\n        // this is where you could do the heavy lifting of "loading" the app\n        PullDataFromDatabase();\n        DoLoadingWork();            \n\n        // ready to go, now close the splash\n        FormSplash.CloseSplash();\n    }\n</code></pre>\n\n<p>I had issues with the <code>Microsoft.VisualBasic</code> solution -- Worked find on XP, but on Windows 2003 Terminal Server, the main application form would show up (after the splash screen) in the background, and the taskbar would blink. And bringing a window to foreground/focus in code is a whole other can of worms you can Google/SO for.</p>\n'}, {'answer_id': 6744070, 'author': 'Reabetswe Molefe', 'author_id': 851539, 'author_profile': 'https://Stackoverflow.com/users/851539', 'pm_score': 2, 'selected': False, 'text': '<pre><code>private void MainForm_Load(object sender, EventArgs e)\n{\n     FormSplash splash = new FormSplash();\n     splash.Show();\n     splash.Update();\n     System.Threading.Thread.Sleep(3000);\n     splash.Hide();\n}\n</code></pre>\n\n<p>I got this from the Internet somewhere but cannot seem to find it again. Simple but yet effective.</p>\n'}, {'answer_id': 8234046, 'author': 'Patratacus', 'author_id': 179037, 'author_profile': 'https://Stackoverflow.com/users/179037', 'pm_score': 2, 'selected': False, 'text': "<p>I like Aku's answer a lot, but the code is for C# 3.0 and up since it uses a lambda function.  For people needing to use the code in C# 2.0, here's the code using anonymous delegate instead of the lambda function.  You need a topmost winform called <code>formSplash</code> with <code>FormBorderStyle = None</code>.  The <code>TopMost = True</code> parameter of the form is important because the splash screen might look like it appears then disappears quickly if it's not topmost.  I also choose <code>StartPosition=CenterScreen</code> so it looks like what a professional app would do with a splash screen.  If you want an even cooler effect, you can use the <code>TrasparencyKey</code> property to make an irregular shaped splash screen.</p>\n\n<pre><code>private void formMain_Load(object sender, EventArgs e)\n  {\n\n     Hide();\n     bool done = false;\n     ThreadPool.QueueUserWorkItem(delegate\n     {\n       using (formSplash splashForm = new formSplash())\n       {\n           splashForm.Show();\n           while (!done)\n              Application.DoEvents();\n           splashForm.Close();\n       }\n     }, null);\n\n     Thread.Sleep(2000);\n     done = true;\n     Show();\n  }\n</code></pre>\n"}, {'answer_id': 18376592, 'author': 'Colonel Panic', 'author_id': 284795, 'author_profile': 'https://Stackoverflow.com/users/284795', 'pm_score': 2, 'selected': False, 'text': "<p>I disagree with the other answers recommending <code>WindowsFormsApplicationBase</code>. In my experience, it can slow your app. To be precise, while it runs your form's constructor in parallel with the splash screen, it postpone your form's Shown event.</p>\n\n<p>Consider an app (without splashs screen) with a constructor that takes 1 second and a  event handler on Shown that takes 2 seconds. This app is usable after 3 seconds.</p>\n\n<p>But suppose you install a splash screen using  <code>WindowsFormsApplicationBase</code>. You might think <code>MinimumSplashScreenDisplayTime</code> of 3 seconds is sensible and won't slow your app. But, try it, your app will now take 5 seconds to load.</p>\n\n<hr>\n\n<pre><code>class App : WindowsFormsApplicationBase\n{\n    protected override void OnCreateSplashScreen()\n    {\n        this.MinimumSplashScreenDisplayTime = 3000; // milliseconds\n        this.SplashScreen = new Splash();\n    }\n\n    protected override void OnCreateMainForm()\n    {\n        this.MainForm = new Form1();\n    }\n}\n</code></pre>\n\n<p>and</p>\n\n<pre><code>public Form1()\n{\n    InitializeComponent();\n    Shown += Form1_Shown;\n    Thread.Sleep(TimeSpan.FromSeconds(1));\n}\n\nvoid Form1_Shown(object sender, EventArgs e)\n{\n    Thread.Sleep(TimeSpan.FromSeconds(2));\n    Program.watch.Stop();\n    this.textBox1.Text = Program.watch.ElapsedMilliseconds.ToString();\n}\n</code></pre>\n\n<hr>\n\n<p>Conclusion: don't use <code>WindowsFormsApplicationBase</code> if your app has a handler on the Slown event. You can write better code that runs the splash in parallel to both the constructor and the Shown event.</p>\n"}, {'answer_id': 46033441, 'author': 'Do-do-new', 'author_id': 3535036, 'author_profile': 'https://Stackoverflow.com/users/3535036', 'pm_score': 0, 'selected': False, 'text': '<p>Actually mutlithreading here is not necessary.</p>\n\n<p>Let your business logic generate an event whenever you want to update splash screen. </p>\n\n<p>Then let your form update the splash screen accordingly in the method hooked to eventhandler.</p>\n\n<p>To differentiate updates you can either fire different events or provide data in a class inherited from EventArgs.</p>\n\n<p>This way you can have nice changing splash screen without any multithreading headache.</p>\n\n<p>Actually with this you can even support, for example, gif image on a splash form. In order for it to work, call Application.DoEvents() in your handler:</p>\n\n<pre><code>private void SomethingChanged(object sender, MyEventArgs e)\n{\n    formSplash.Update(e);\n    Application.DoEvents(); //this will update any animation\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/48916', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4246/']