Devin Rawlek
Devin Rawlek

Reputation: 127

How can I reduce the MySQL connection delay in while loop?

I have an interface that pulls data from a MySQL database and displays it in a console window. The code used to display the information is cycled using a while loop.

The issue I'm having is that the MySQL connections open and close on each loop and this causes a delay in displaying the information. I have tried opening a connection before the loop and closing it once the loop exits but I get an exemption telling me the connection need to be valid and open.

So the loop adds data from the database into the datalist List and then gets displayed in the console. Each loop also clears the list as the information on the server can change due to updates.

The other thing I'd like to move away from would be the Thread.Sleep() as it hangs the program (as designed I know) but I don't know of other solutions.

Here is my code;

public void Loop()
    {
        public static string loopquery;
        public static List<DataList> datalist;

        var cki = new ConsoleKeyInfo();

        do
        {
            DateTime time = DateTime.Now.AddSeconds(1);

            while ((DateTime.Now < time))
            {
                Console.Clear();
                Travel.data.Clear();

                loopquery = "SELECT * FROM database)";
                Travel();

                Console.WriteLine("Hurray it's a loop!");
                Console.WriteLine(datalist[0].id);
                Console.WriteLine(datalist[0].name);

                if (Console.KeyAvailable)
                {
                    // Waits until the user presses a key, and puts it into our object key.
                    cki = Console.ReadKey(true);

                    if (cki.Key == ConsoleKey.UpArrow)
                    {
                        // Do Something
                    }
                    if (cki.Key == ConsoleKey.DownArrow)
                    {
                        // Do Something
                    }
                    if (cki.Key == ConsoleKey.LeftArrow)
                    {
                        // Do Something
                    }
                    if (cki.Key == ConsoleKey.RightArrow)
                    {
                        // Do Something
                    }
                    if (cki.Key == ConsoleKey.Escape)
                    {
                        break;
                    }
                }
                else
                {
                    Thread.Sleep(1000);
                }

            }
        } while (cki.Key != ConsoleKey.Escape);
    }

public void Travel()
    {
        //Open a connection
        databaseCon.Open();

        //Create Command
        var cmd = new MySqlCommand(Loop.loopquery, databaseCon);

        //Create a data reader and Execute the command
        var dataReader = cmd.ExecuteReader();

        try
        {
            //Read the data and store them in the list
            while (dataReader.Read())
            {
                 var data= new DataList();
                    data.id = (dataReader.GetInt32(0));
                    data.name = (dataReader.GetString(1));

                    Loop.datalist.Add(data);
            }
        }
        catch (MySqlException ex)
        {
            Console.WriteLine("Error: {0}", ex);
            Console.ReadLine();
        }
        finally
        {
            if (dataReader != null)
            {
                //close Data Reader
                dataReader.Close();
            }

            if (databaseCon != null)
            {
                //close Connection
                databaseCon.Close();
            }
        }
    }

Is there a more efficient way to do this? I don't want to hammer the server with hundreds of queries as this client will be used by a number of people.

Upvotes: 1

Views: 1077

Answers (1)

bryanmac
bryanmac

Reputation: 39296

As you pointed out, it might not be efficient for many clients to do hundreds of queries directly against the database in a loop.

There isn't specifics on your app, but one way to avoid a bunch of clients hammering the SQL server in a loop would be to add an application tier between the clients and the database server. You could open an API endpoint (REST etc...) for the clients to query. The application tier server could periodically query and hold the data in memory for all the clients to query.

That of course only makes sense if the many clients are accessing the same data to share or a cacheable set of data is feasible to hold in memory. It also depends on how latent that data can be to determine when you have to evict data from the cache or update.

Yet another option is to create two way communications with something like a socket server where the server calls back to the client when data changes.

If an application tier is also used for writes, then there's other options to invalidate data in the cache on change.

Upvotes: 1

Related Questions