我正在使用C#编写我的第一个Windows服务,我的Timer类遇到了一些问题。
当服务启动时,它会按预期运行,但代码不会再次执行(我希望它每分钟运行一次)
请快速查看所附的来源,如果您发现任何明显的错误,请告诉我们!
TIA
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.IO;
namespace CXO001
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
/*
* Aim: To calculate and update the Occupancy values for the different Sites
*
* Method: Retrieve data every minute, updating a public value which can be polled
*/
protected override void OnStart(string[] args)
{
Daemon();
}
public void Daemon()
{
TimerCallback tcb = new TimerCallback(On_Tick);
TimeSpan duetime = new TimeSpan(0, 0, 1);
TimeSpan interval = new TimeSpan(0, 1, 0);
Timer querytimer = new Timer(tcb, null, duetime, interval);
}
protected override void OnStop()
{
}
static int[] floorplanids = new int[] { 115, 114, 107, 108 };
public static List<Record> Records = new List<Record>();
static bool firstrun = true;
public static void On_Tick(object timercallback)
{
//Update occupancy data for the last minute
//Save a copy of the public values to HDD with a timestamp
string starttime;
if (Records.Count > 0)
{
starttime = Records.Last().TS;
firstrun = false;
}
else
{
starttime = DateTime.Today.AddHours(7).ToString();
firstrun = true;
}
DateTime endtime = DateTime.Now;
GetData(starttime, endtime);
}
public static void GetData(string starttime, DateTime endtime)
{
string connstr = "Data Source = 192.168.1.123; Initial Catalog = Brickstream_OPS; User Id = Brickstream; Password = bstas;";
DataSet resultds = new DataSet();
//Get the occupancy for each Zone
foreach (int zone in floorplanids)
{
SQL s = new SQL();
string querystr = "SELECT SUM(DIRECTIONAL_METRIC.NUM_TO_ENTER - DIRECTIONAL_METRIC.NUM_TO_EXIT) AS 'Occupancy' FROM REPORT_OBJECT INNER JOIN REPORT_OBJ_METRIC ON REPORT_OBJECT.REPORT_OBJ_ID = REPORT_OBJ_METRIC.REPORT_OBJECT_ID INNER JOIN DIRECTIONAL_METRIC ON REPORT_OBJ_METRIC.REP_OBJ_METRIC_ID = DIRECTIONAL_METRIC.REP_OBJ_METRIC_ID WHERE (REPORT_OBJ_METRIC.M_START_TIME BETWEEN '" + starttime + "' AND '" + endtime.ToString() + "') AND (REPORT_OBJECT.FLOORPLAN_ID = '" + zone + "');";
resultds = s.Go(querystr, connstr, zone.ToString(), resultds);
}
List<Record> result = new List<Record>();
int c = 0;
foreach (DataTable dt in resultds.Tables)
{
Record r = new Record();
r.TS = DateTime.Now.ToString();
r.Zone = dt.TableName;
if (!firstrun)
{
r.Occupancy = (dt.Rows[0].Field<int>("Occupancy")) + (Records[c].Occupancy);
}
else
{
r.Occupancy = dt.Rows[0].Field<int>("Occupancy");
}
result.Add(r);
c++;
}
Records = result;
MrWriter();
}
public static void MrWriter()
{
StringBuilder output = new StringBuilder("Time,Zone,Occupancy\n");
foreach (Record r in Records)
{
output.Append(r.TS);
output.Append(",");
output.Append(r.Zone);
output.Append(",");
output.Append(r.Occupancy.ToString());
output.Append("\n");
}
output.Append(firstrun.ToString());
output.Append(DateTime.Now.ToFileTime());
string filePath = @"C:\temp\CXO.csv";
File.WriteAllText(filePath, output.ToString());
}
}
}
答案 0 :(得分:4)
只要您使用Timer,就必须保留对它的引用。与任何托管对象一样,当没有对它的引用时,Timer会进行垃圾回收。定时器仍处于活动状态这一事实并不能阻止它被收集。
您的计时器可能正由GC收集。