System.Threading.Timer不会触发我的TimerCallBack委托

时间:2011-01-17 09:49:11

标签: c# windows-services timer

我正在使用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());
        }

    }
}

1 个答案:

答案 0 :(得分:4)

manual states

  

只要您使用Timer,就必须保留对它的引用。与任何托管对象一样,当没有对它的引用时,Timer会进行垃圾回收。定时器仍处于活动状态这一事实并不能阻止它被收集。

您的计时器可能正由GC收集。