我有一个窗口,我在OnStart()方法中添加了一个无限的while循环。我已经测试了1小时的服务并且运行正常。但这是我的第一个Windows Service
所以有怀疑无限循环的性能。
这是代码..
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() {
}
所以想知道长跑是否合适。谢谢..
答案 0 :(得分:4)
您几乎肯定不想在无限循环中查询数据库。您可能想要做的是使用Timer每隔一段时间(例如每30秒)查询一次数据库,并在某些情况匹配时做一些工作,例如。
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
}
}
}
}
根据更新速度的重要程度,您还可以了解情况并引入补偿策略。例如,这是一个非常简单的增量退避:
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);
}
}
答案 1 :(得分:4)
每40秒重新运行一次查询:
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();
}
}
}
这样的事情。 正如Groo所提到的那样,你可能希望每次都处理这种连接,这样你就不会在内存中闲置它。
答案 2 :(得分:1)
试试这个
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);
}
}
答案 3 :(得分:1)
或者你可以在新线程中启动它而不使用计时器
var threadStart = new ThreadStart(<your method delegate>);
var thread = new Thread(threadStart);
thread.Start();