Reputation: 127
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
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