Is there a better way to implement a time consumin

2019-07-31 07:30发布

问题:

I have an application that uses many controls which can take a very long time to intitialize (On the order of 10 to 30 seconds). So I use a splash screen for my application to load them up and present the user with some sense of satisfaction that something is happening. I display a spinning gif and a progress bar.

Because I am pre-loading controls, it seemed the only way to do this was on the main UI thread. Then I discovered Microsoft.VisualBasic.ApplicationServices. Now I do my spalsh screen like this.

Program.cs:

using System;
using System.Reflection;
using System.Windows.Forms;
using Spectrum.Foxhunt.Forms;
using Spectrum.UI;
using Microsoft.VisualBasic.ApplicationServices;

namespace Spectrum.Foxhunt
{
    static class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            new SplashLoader().Run(args);
        }
    }

    class SplashLoader : WindowsFormsApplicationBase
    {
        private Main main;
        private Splash splash;

        public SplashLoader()
        {
            main = new Main();
            splash = new Splash();
        }

        protected override void OnCreateSplashScreen()
        {
            this.SplashScreen = splash;
        }

        protected override void OnCreateMainForm()
        {
            main.SplashScreenWork(splash);
            this.MainForm = main;
        }
    }
}

Splash.cs:

Just a form with a graphic that represents my application, version information, a spinning gif, and a progress bar.

namespace Spectrum.Foxhunt.Forms
{
    public partial class Splash : Form
    {
        public int Progress { set { progress.Value = value; } }

        public Splash()
        {
            InitializeComponent();

            version.Text = "Version " + typeof(Main).Assembly.GetName().Version;
        }
    }
}

Main.cs:

Has an empty constructor and my method which does all the work while the splash screen is displayed.

public Main()
{
    InitializeComponent();
}

public void SplashScreenWork(Splash splash)
{
    // Create time-consuming control
    splash.Progress = 25;
    // Create time-consuming control
    splash.Progress = 50;
    // Create time-consuming control
    splash.Progress = 75;
    // Create time-consuming control
    splash.Progress = 100;
}

I like this method because it seems to eliminate of the threading issues I was having with trying to do this work in a background worker. And, my spinnning gif in the splash form continues to spin despite all the work going on in the background.

That being said, I wonder if there is a better way to implement a splash screen that is loading controls while still allowing a spinning gif to spin and a progress bar to update on the splash screen.