1

I´m programming an installer that installs new software and so on and, in addition, I want to read some hardware stuff like CPU architecture and so on. But this takes a while, so I want to display a splash screen while the program reads the hardware. But it won´t display and I don´t know why.

Can someone help me, please?

In the Header of the Mainclass I create a new Thread:

public Hauptfenster()
        {
            InitializeComponent();
            t = new Thread(new ThreadStart(ZeigeLadeBildschirm));
            t.Start();
        }

When the Thread starts the SplashScreen should be displayed and the hardware should be read by the Mainclass. So the method "ZeigeBildschirm" says:

public void ZeigeLadeBildschirm()
    {
        SplashScreen sp = new SplashScreen();

        sp.Show();
        createFolder();
        entpacken();
        Verionszahlalsd();
        GetHardwareInformationRAM();
        GetOSInformation();
        GetReleaseDateBIOS();
        GetLastBootTime();
        GetHardwareInfoVideo();
        GetHardwareInfoMonitor();
        GetSystemInfo();
        GetCDDriveInformation();
        GetDiskDriveInformation();
        GetHardwareInfoCPU();
        GetInstallDateWindows();

    }

to stop the Mainthread while the new Thread reads out the hardware I coded this after creation of the Thread in the Header:

while (t.IsAlive)
    {
    }

So the Header looks like this:

public Hauptfenster()
        {
            InitializeComponent();
            Initialisierung();
            t = new Thread(new ThreadStart(ZeigeLadeBildschirm));
            t.Start();
            while (t.IsAlive)
            {
            }
            GetAdditionRAMInfo();
            SchreibeDaten();
        }

But when I start the program, the hardware is read out but no SplashScreen is displayed on the screen. After the hardware reading code is finished, the MainForm opens and shows all data. How can I fix that code, so that the SplashScreen will be displayed, the hardware will be read out and the SplashScreen disappears and the MeinForm will be displayed?

Code of SplashScreen:

namespace The5thBlueskyInstallerSplashScreen
{
    public partial class SplashScreen : Form  

    {

        public SplashScreen()
        {
            InitializeComponent();
        }
    }
}
Mark Hurd
  • 10,665
  • 10
  • 68
  • 101
  • It seems that your `while` is waiting in the main thread and blocks the UI. – Filipe Borges Mar 30 '16 at 16:05
  • I opened the question as the title was interesting but looked up the SplashScreen class and it says: "The splash screen is displayed by using native code, before the WPF application instance is created.". From this it seems when you want to use it's too late already. Try using (instead of threading) the .Show(bool) method, read HW, then the .Close(timeSpan) method when you are done. Just guessing but worths a try. –  Mar 30 '16 at 16:10
  • @Mark, this is WinForms, not WPF, and the (partial) code for SplashSceen is within the question. – Andrew Savinykh Mar 30 '16 at 21:15
  • @AndrewSavinykh Awh, true. Sorry I was sloppy on that ;) –  Mar 31 '16 at 12:52
  • Take a look at [Windows Forms Splash Screen](https://stackoverflow.com/a/32421479/3110834). – Reza Aghaei Dec 02 '19 at 05:42

1 Answers1

1

You need to do all UI on the main thread.

Just shift the splash screen creation and showing to the main class, before creating the thread, and close it, from the main thread, after the extra thread completes.

It would be preferable to use events, but, with my suggestion in comments to use DoEvents, a minimal (untested) change would be:

public Hauptfenster()
    {
        InitializeComponent();
        Initialisierung();
        SplashScreen sp = new SplashScreen();
        sp.Show();
        t = new Thread(new ThreadStart(ZeigeLadeBildschirm));
        t.Start();
        while (t.IsAlive)
        {
            System.Windows.Forms.Application.DoEvents();
            System.Windows.Forms.Application.DoEvents();
            Thread.Sleep(55);
        }
        GetAdditionRAMInfo();
        SchreibeDaten();
        sp.Close();
    }

And remove the sp references in the other thread.

Mark Hurd
  • 10,665
  • 10
  • 68
  • 101
  • if i try this an code the Header so : `InitializeComponent(); Initialisierung(); this.Hide(); SplashScreen sp = new SplashScreen(); sp.Show(); t = new Thread(new ThreadStart(ZeigeLadeBildschirm)); t.Start(); while (t.IsAlive) { } sp.Close(); GetAdditionRAMInfo(); SchreibeDaten();` the SplashScreen will never displayed – The5thBluesky Mar 30 '16 at 16:26
  • Yes, because you're not allowing anything to happen while you're waiting for the thread to finish. – Mark Hurd Mar 30 '16 at 16:38
  • That is, if you don't want to do it based upon events, you'll need to call `System.Windows.Forms.Application.DoEvents` from the main thread yourself. – Mark Hurd Mar 30 '16 at 16:44
  • can you show me please where exactly i have to write `System.Windows.Forms.Application.DoEvents` ? – The5thBluesky Mar 30 '16 at 17:07
  • I suggest @The5thBluesky reads up on what message pump in windows is. Without windows procedure able to do anything no UI can meaningfully happen. So, in winforms you do all UI work on UI thread and you do all other work in additional threads, not the other way around. And you never block on the UI thread. And then everything works. That's really simple, once you understand how it's wired together internally. – Andrew Savinykh Mar 30 '16 at 21:21