user3134679
user3134679

Reputation: 53

Splash Screen Not Closing Based Off Progress Bar

Form1.cs

public Form1()
    {
        Thread SplashThread = new Thread(new ThreadStart(SplashScreen));
        SplashThread.Start();
        Thread.Sleep(5000);

        SplashThread.Abort();

        InitializeComponent();

        this.BringToFront();

        PlayerOne[1] = new BladeWarrior();
        PlayerOne[2] = new FistWarrior();
        PlayerOne[3] = new Archer();
        PlayerOne[4] = new RedMage();
        PlayerOne[5] = new BlueMage();

    }
    public void SplashScreen()
    {
        Application.Run(new SplashScreen());
    }

SplashScreen.cs

public SplashScreen()
        {
            InitializeComponent();

            LoadGearFiles LoadGear = new LoadGearFiles();

            LoadGear.StartPatching(this);

        }
        Timer t = new Timer();


        void t_Tick(object sender, EventArgs e)
        {


            if (LoadingBar.Value == 100) t.Stop();

        }

LoadGearFiles.cs

public void StartPatching(SplashScreen Splash)
        {
            Splash.PatchingLabel.Text = "Patching in progress! This may take a moment or two!";
            Thread.Sleep(SleepTime);
            Splash.LoadingBar.Value += 25;

            LoadWeapons(Splash);
            Splash.LoadingBar.Value += 25;
            LoadArmor(Splash);
            Splash.LoadingBar.Value += 25;
            LoadRings(Splash);
            Splash.LoadingBar.Value += 25;
            Splash.PatchingLabel.Text = "Patch Complete!";
        }

My problem is that my Splash Screen shows but closes based of the Thread.Sleep(5000) and not the progress bar value being equal to its maximum. If I comment out Thread.Sleep(5000) the splash screen closes almost instantly. In the LoadGearFiles class, there's nothing special, its just stream readers/writers reading and writing to notepad files,loading the information into arrays. They read/write/populate successfully. Also, in the load gear files class, I increase the value of the progress bar after certain files are read from or written to. What seems to be my problem here. What sort of logical/syntactical approach should I take?

Upvotes: 0

Views: 375

Answers (2)

Mustafa Chelik
Mustafa Chelik

Reputation: 2184

Open your form, in Timer_Tick:

void Timer1_Tick(object sender, EventArgs e)
{
    progressBar1.PerformStep();
    if(progressBar1.Value == 100)
    {
        Timer.Enabled = false;
        Form1 form1 = new Form1();
        form1.Show();
        this.Hide(); //or Close maybe (test them both)
    }
}

Upvotes: 1

Erik
Erik

Reputation: 12858

I'm assuming you're using WinForms from your code. It looks like you want to show the splash screen for a minimum duration, or until all files are loaded successfully -- whichever comes last.

Assuming you have access to the C# 4.0's Task and the async/await keywords of C# 5.0, I'd highly recommend staying away from Thread.Sleep. It's a fairly old construct that is not very efficient for modern multithreading programs. Even if you don't have the latter, using Task is preferred and you will see why the more you use them.

Let's break down your logic into tasks:

  1. Show the Splash Screen.
  2. Load in a data file asynchronously.
  3. Update progress on the UI thread.
  4. Repeat steps 2-3 for each additional data file.
  5. Ensure the Splash Screen has been displayed for at least n seconds.
  6. Close the splash screen.

Let's look at it in a form of C# code (which I'm writing largely off the top of my head, not in an IDE):

public async void ShowSplashScreen(TimeSpan minimumDuration)
{
    // Show the splash screen to the user.
    var splashScreen = new SplashScreen();
    splashScreen.Show();
    splashScreen.UpdateProgress(0);  // reset progress bar

    // Record when we started to load data for calculating the elapsed time later on.
    var startTime = DateTime.Now;

    // Load all of our data types asynchronously from file.
    var warrior = await LoadDataFileAsync("warrior.dat");
    splashScreen.UpdateProgress(20); // 20%

    var archer = await LoadDataFileAsync("archer.dat");
    splashScreen.UpdateProgress(40); // 40%

    var redMage = await LoadDataFileAsync("redMage.dat");
    splashScreen.UpdateProgress(60); // 60%

    var blueMage = await LoadDataFileAsync("blueMage.dat");
    splashScreen.UpdateProgress(80); // 80%

    var fistWarrior = await LoadDataFileAsync("fistWarrior.dat");
    splashScreen.UpdateProgress(100); // 100% -- all done

    // Determine the elapsed time to load all data files, and the remaining time to display the splash screen.
    var elapsedTime = DateTime.Now - startTime;
    var remainingTimeToWait = minimumDuration - elapsedTime;

    // If we've completed early, wait the remaining duration to show the splash screen.
    if(remainingTimeToWait > TimeSpan.Zero)
      await Task.Delay(remainingTimeToWait);

    // Done loading, close the splash screen.
    splashScreen.Close();
}

Now your LoadDataFileAsync method would look something like this:

Task<object> LoadDataFileAsync(string file)
{
    // Do your work to load your data file into an object here.
}

EDIT: I've been alerted to your comment that you are using .NET 4.0 so you have Task but not necessarily async/await. In this case, you can still break your code up into Task but will have to use .ContinueWith().

See here for some good examples: How to: Chain Multiple Tasks with Continuations

Upvotes: 1

Related Questions