Resolved SQL Test causing significant form loading time

ConsKa

Well-known member
Joined
Dec 11, 2020
Messages
140
Programming Experience
Beginner
I noted my form takes awhile to load after an initial Message box requesting the user confirm a new session or not.

Looking through it, it appears that the delay occurs at this part:

Program.cs:

C#:
static void main()
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(fale);
    If (SqlTest(@"...connectionstring....")
        Application.Run(new Form1());
        
private static bool SqlTest(String connectionString)
        // check whether a connection has been made return false if no connection

Now, I like the fact that the connection is being tested, but I dislike that the form takes a good 20 secs to load while it does this (connection isn't local). There is a thread here - Resolved - just close application?

Where I first discussed the problem.

I would like for the form to load, and if the sql test fails, then provide a messagebox and then close as the form shouldn't be used without that connection - I just think it is bad to load an application and then have nothing happen for awhile....I would rather that it loaded and then if necessary booted the user out and closed.

Given the issues I had before, I thought I would ask and see if anyone had any ideas. Thanks.
 
Solution
Your SQL connection is tying up the main UI thread. By putting in the pause there, you yield the UI thread long enough for the screen to be painted. Perhaps responding on a phone is really a no-no for me.

Here's the correct sequence of things to do:
1) Show you splash screen
2) In your splash screen's Shown event, fire of a background worker thread, as well as a timer.
3) The background worker, check to see if the SQL connection will work, but simply set a flag to true or false depending on whether the connection can be made, and also a flag that indicates that SQL check has been completed.
4) In the timer event handler check if the SQL check has been completed.
5) If the check has been completed, then you can hide the splash screen...
Then move the SQL check into the Form's Shown event. Note: The Shown event, not the Loaded event. Also if that is still too long of a gap, read about splash screens. Have you considered a splash screen do the SQL check and let it declare the SQL connection is bad, or appropriately start the program if it is good?
 
Last edited:
Then move the SQL check into the Form's Shown event. Note: The Shown event, not the Loaded event. Also if that is still too long of a gap, read about splash screens. Have you considered a splash screen do the SQL check and let it declare the SQL connection is bad, or appropriately start the program if it is good?

Thanks in the process of adding a splash screen, which works fine as a canvas for connecting to the database and covering the short connection delay....however, when you cannot connect, it doesn't show the splashscreen, until the message pops up to say you cannot connect to the database...

I have tried moving the code around, but not sure why it isn't showing the splashscreen.

C#:
public void Splash_Shown(object senter, EventArgs e)
{
    SqlTest(connectionstring)
}
public bool SqlTest(String connectionString)
{
    using SqlConnection connection = new SqlConnection(connectionString)
    {
        try
        {
            connection.Open();
            Form1 mf = new Form1();
            mf.Show();
            this.Hide();
            return true;
        }
        catch (SqlException)
        {
            MessageBox.Show("Could not connect");
            this.Close();
            return false;
        }
       
    }
}

I did previously have the if statement in the Splash_shown with the try catch in the SqlTest method...but neither seems to work.

For ease of reference it looked like this:

C#:
public void Splash_Show(object sender, EventArgs e)
{
    if (SqlTest(connectionString))
    {
        Form1 mf = new Form1();
        mf.Show();
        this.Hide();
    }
    else
    {
        this.Close();
    }
}
public static bool SqlTest(String connectionString)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        try
        {
            connection.Open();
            return true;
        }
        catch (SqlException)
        {
            NessageBox.Show("Could not connect");
            return false;
        }
    }
}
 
Well bizarrely writing:

C#:
Wait(10);

Makes the splashscreen show up while completing the test....no idea why it needed a millisecond to work, but apparently it does.

(I have a wait method in my main program and I am calling it here).
 
Your SQL connection is tying up the main UI thread. By putting in the pause there, you yield the UI thread long enough for the screen to be painted. Perhaps responding on a phone is really a no-no for me.

Here's the correct sequence of things to do:
1) Show you splash screen
2) In your splash screen's Shown event, fire of a background worker thread, as well as a timer.
3) The background worker, check to see if the SQL connection will work, but simply set a flag to true or false depending on whether the connection can be made, and also a flag that indicates that SQL check has been completed.
4) In the timer event handler check if the SQL check has been completed.
5) If the check has been completed, then you can hide the splash screen.
6) If the connection cannot be made, then show the error message and later quit.
7) Else (the connection can be made), then show your main form.

I'm quite saddened by the current crop of Google search results showing how to show a splash screen. Although the approaches given there would work, they are actually not the correct way to do splash screen. The correct way involves swapping the Application.MainForm from the splash screen to the true main form, but it seems like that bit of lore has been lost.
 
Solution
I guessed that the If statement was tying it up, simply because it was in the Shown method and ...well what else could it be. That is why I tried the Wait.

I have been reading about Background worker tasks earlier today, and also been watching a few tutorials on async.

Not really sunk in yet if I am honest, another read and watch and I might start to grasp it. Also think I need to start a new project and use these ideas, as trying to force them into my old project isn't really working for me. I think when I get a better grasp on them then I return and see if I can fit them in.
 
WinForms apps are event driven. Time to learn about event-driven programming and how it works.

The quick and dirty summary is this: Windows apps run in a tight loop that gets a message from either the OS or the program itself and it sends that message to the appropriate message handler. When a key is pressed, a message is sent to the window with the current focus to deal with the keypress. Then it returns control to the loop. A key is released, a message is sent to the window with the current focus to deal with the current release. Then it returns control to the loop. The mouse has moved. Same thing. The window needs to be repainted. Same thing. The computer is fast enough, and each of the handlers are quick enough to do their operations, and then hand back control to the tight loop. When an event handler takes a long time, then obviously, the loop doesn't get a chance to get the next message and send it to the appropriate handler. Your SQL test takes a long time.
 
That's no excuse for using something as dated and shitty as Winforms.

If you want help with moving to WPF, you can ask on the forums, as you know, there are many here who will help you. I'd urge you to use WPF, and learn it today. Yes it comes with a learning curve, but it's worth it.
 
Well the app is complete in Win Form so gives me a bit of free time to try and get it into a WPF.

I always feel there is a difference between asking for assistance because a piece of code won't behave as you think it would, and basically asking someone to write your code for you.

I will have a crack again at the WPF, I got about 30% in and hit a wall, and still had a lot of work to do to finish the app I was working on - so will see if I can get the last 70% done.
 
Yea, I hear ya. The transition has quite a curve to it for anyone coming from the Winforms side... as almost everything in WPF is done differently to how one would be used to doing in Winforms, and this is often the reason why most learners revert back to Winforms. But now you will need to develop your app in WPF, which will likely cost you countless hours in redevelopment. I'd say its not worth it, except you will gain experience from it. Which is of course a good thing.

Given you are also a beginner, it would have been more worth your time to undertake the dev experience from learning WPF instead.

Regarding this :
I always feel there is a difference between asking for assistance because a piece of code won't behave as you think it would, and basically asking someone to write your code for you.
Don't worry about that on these forums. Providing you have shown an attempt to write your own logic, and regardless how bad that logic/source code may be. We only care that you've made an attempt at writing your own code before asking for help, and with that, we are always happy to help anyone out.
 
Back
Top Bottom