【问题标题】:Polling Service - C#轮询服务 - C#
【发布时间】:2011-08-24 06:39:27
【问题描述】:

有人可以帮助我吗?

我正在创建一个连接到 sql 数据库并检查表中的日期并将其与今天的日期进行比较并更新该数据库中的字段的 Windows 服务,例如,如果日期等于今天的日期,那么该字段将为设置为真。

我遇到的问题是,当我启动服务时,它并没有这样做,但是当我以正常形式执行时,它工作得很好。

我的代码如下:

//System.Timers
Timer timer = new Timer();
protected override void OnStart(string[] args)
{
    timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
    timer.Interval = 60000;
    timer.Enabled = true;
}

private void OnElapsedTime(object source, ElapsedEventArgs e)
{
    int campid = 0;
    var campRes = new ROS.Process.CampaignServiceController().GetCampainInfo();

    foreach (var s in campRes)
    {
        campid = s.CampaignId;

        if (s.CampEndDate.Date < DateTime.Today.Date)
        {
            //WriteDataToFile("Not Active : " + campid.ToString());
            new ROS.Process.CampaignServiceController().SetCampainStatusFalse(campid);
        }
        else
        {
            //WriteDataToFile("Active : " + campid.ToString());
            new ROS.Process.CampaignServiceController().SetCampainStatusTrue(campid);
        }
    }
}

【问题讨论】:

  • 你能验证OnElapsedTime是否正在运行?
  • 哪一部分失败了?您是否使用过记录器来检查 onelapsed 方法是否被触发?
  • 是的,我可以验证,因为我以普通的 Windows 形式运行它并且它运行良好
  • 您检查应用程序事件日志是否有错误?
  • 我如何使用记录器?

标签: c# service polling


【解决方案1】:

另一种方法是等待事件而不是使用计时器。

    public class PollingService
    {
        private Thread _workerThread;
        private AutoResetEvent _finished;
        private const int _timeout = 60*1000;

        public void StartPolling()
        {
            _workerThread = new Thread(Poll);
            _finished = new AutoResetEvent(false);
            _workerThread.Start();
        }

        private void Poll()
        {
            while (!_finished.WaitOne(_timeout))
            {
                //do the task
            }
        }

        public void StopPolling()
        {
            _finished.Set();
            _workerThread.Join();
        }
    }

为您服务

    public partial class Service1 : ServiceBase
    {
        private readonly PollingService _pollingService = new PollingService();
        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            _pollingService.StartPolling();
        }

        protected override void OnStop()
        {
            _pollingService.StopPolling();
        }

    }

【讨论】:

    【解决方案2】:

    设置 Timer.AutoReset = true。否则它只会做一次它的工作。但最好在 Windows 服务中使用线程。

    [编辑] 是啊。 autoreset 默认为 true。我也把它放在我的代码中: GC.KeepAlive(myTimer); 所以如果它处于非活动状态,gc 不会删除它。

    【讨论】:

    • 但是如果你省略 Timer.AutoReset 编译器会假定它是真的,这不是真的吗?
    • 好吧,你说默认情况下垃圾收集器会在定时器不在 ontimeelapsed 事件中时丢弃它?
    • 我不确定我是在哪里读到的。可能在这里:stackoverflow.com/questions/477351/…
    • 在这里我找到了可以使用的东西:codeguru.com/columns/dotnet/article.php/c6919
    • 非常感谢所有帮助将测试它是否有效
    猜你喜欢
    • 2015-04-08
    • 2013-11-11
    • 2021-12-29
    • 2013-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    相关资源
    最近更新 更多