Endless while loop in Windows service
I have windows where I added an infinite while loop in the OnStart () method. I have tested the service for 1 hour and it works fine. But since this is my first one Windows Service
, so doubt the performance with an infinite loop. Here is the code.
protected override void OnStart(string[] args)
{
while(true){
string Query="";
Query = "SELECT * FROM 'reportsetting` order by SendingTime;";
MySqlConnection con = new MySqlConnection(conn);
MySqlCommand comm = new MySqlCommand(Query, con);
con.Open();
MySqlDataReader dr = comm.ExecuteReader();
while (dr.Read())
{
time = dr["SendingTime"].ToString();
if ((str = DateTime.Now.ToString("HH:mm")).Equals(time))
{
//Execute Function and send reports based on the data from the database.
Thread thread = new Thread(sendReports);
thread.Start();
}
}
//Halt for this Moment
while ((str = DateTime.Now.ToString("HH:mm")).Equals(time))
{
}
}
}
public void sendReports() {
}
So I want to know if this will be ok for a long run. Thank..
source to share
Retrying the query every 40 seconds:
private const string Query = "SELECT * FROM 'reportsetting` order by SendingTime;"
protected override void OnStart(string[] args)
{
_timer = new Timer(40 * 1000); // every 40 seconds
_timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
_timer.Start(); // <- important
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
MySqlConnection con = new MySqlConnection(conn);
MySqlCommand comm = new MySqlCommand(Query, con);
con.Open();
MySqlDataReader dr = comm.ExecuteReader();
while (dr.Read())
{
time = dr["SendingTime"].ToString();
if ((str = DateTime.Now.ToString("HH:mm")).Equals(time))
{
//Execute Function and send reports based on the data from the database.
Thread thread = new Thread(sendReports);
thread.Start();
}
}
}
Something like that. As Groo mentioned, you might want to get rid of the connection every time so you don't have it in your mind.
source to share
You almost certainly don't want to query the DB in an infinite loop. What you probably want to do is use Timer to query the DB as often (e.g. every 30 seconds) and do some work if some condition is agreed, e.g.
private static Timer timer;
private const int TimerInterval = 30000;
protected override void OnStart(string[] args)
{
var callback = new TimerCallback(checkDatabase);
this.timer = new Timer(callback, null, 0, TimerInterval);
}
private void checkDatabase()
{
string query = "SELECT * FROM 'reportsetting` order by SendingTime;";
using (var con = new MySqlConnection(conn))
using (var cmd = new MySqlCommand(query, con))
{
con.Open();
using (var dr = cmd.ExecuteReader())
{
while (dr.Read())
{
// do some work
}
}
}
}
Depending on how important the speed of updates is, you can also keep abreast of developments and introduce a retreat strategy. For example, here's a very simple incremental shutdown:
private const int DefaultInterval = 40000;
private int interval = DefaultInterval;
...
while (dr.Read())
{
if (someCondition)
{
// do some work
timer.Change(DefaultInterval, DefaultInterval); // revert to 40 seconds
}
else
{
// no change? increase polling by 10 seconds
interval += 10000;
timer.Change(interval, interval);
}
}
source to share
try it
bool _IsStop = false;
protected override void OnStart(string[] args)
{
base.OnStart(args);
while (!this._IsStop)
{
this.Process();
//40 seconds time out
Thread.Sleep(1000*40); //1000 is 1 second
}
//If we reach here
//Do some clean up here
}
protected override void OnStop()
{
//Service is stop by the user on service or by OS
this._IsStop = true;
}
private void Process()
{
string Query = "";
// -->>> if you use something like this on your query and little bit setup on your db
// this will give you a more efficient memory usage
Query = "SELECT * FROM reportsetting where [your tag if already sent] = false and SendingTime <= [current date and time] order by SendingTime;";
MySqlConnection con = new MySqlConnection(conn);
MySqlCommand comm = new MySqlCommand(Query, con);
con.Open();
MySqlDataReader dr = comm.ExecuteReader();
while (dr.Read())
{
//Execute Function and send reports based on the data from the database.
Thread thread = new Thread(sendReports);
thread.Start();
//sleep for half a second before proceeding to the next record if any
Thread.Sleep(500);
}
}
source to share