首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >System.Timers不能正常工作

System.Timers不能正常工作
EN

Stack Overflow用户
提问于 2016-08-03 16:14:18
回答 2查看 162关注 0票数 0

嗨,我正在编写一个windows和wpf服务,每天在同一时间9:00自动发送电子邮件。web服务工作正常,windows服务每天在我的本地系统中也工作得很好。在服务器系统中,它不能在适当的时间工作。

代码语言:javascript
复制
protected override void OnStart(string[] args)
{
    this.WriteToFile("Simple Service started {0}");
    this.ScheduleService();
}

protected override void OnStop()
{
    this.ServicesStop();
    this.WriteToFile("Simple Service stopped {0}");
    this.Schedular.Dispose();
}

private Timer Schedular;

public void ScheduleService()
{
    try
    {
        //Set the Default Time.
        //DateTime scheduledTime = DateTime.MinValue;
        //Get the Scheduled Time from AppSettings.
        DateTime scheduledTime = DateTime.Parse(System.Configuration.ConfigurationManager.AppSettings["ScheduledTime"]);
        WriteToFile("Service entered " + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss:FFF tt"));

        TimeSpan timeSpan = scheduledTime.Subtract(DateTime.Now);
        if ((timeSpan.Days < 0 || timeSpan.Hours < 0 || timeSpan.Minutes < 0 || timeSpan.Seconds < 0))
        {
            scheduledTime = scheduledTime.AddDays(1);
            timeSpan = scheduledTime.Subtract(DateTime.Now);
        }

        string schedule = string.Format("{0} day(s) {1} hour(s) {2} minute(s) {3} seconds(s)", timeSpan.Days, timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds);

        this.WriteToFile("Simple Service scheduled to run after: " + schedule + " {0}");

        //Get the difference in Minutes between the Scheduled and Current Time.
        Int64 dueTime = Convert.ToInt64(timeSpan.TotalMilliseconds);
        this.WriteToFile("dueTime to be fired: " + dueTime + " {0}");
        //Change the Timer's Due Time.
        Schedular = new Timer(dueTime);
        Schedular.Elapsed += new ElapsedEventHandler(Elpaesdtime);
        Schedular.Enabled = true;
    }
    catch (Exception ex)
    {
        WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace);

        //Stop the Windows Service.
        using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController("SimpleService"))
        {
            serviceController.Stop();
        }
    }
}

private void Elapsedtime(object sender, System.Timers.ElapsedEventArgs e)
{
    DateTime scheduledTime = DateTime.Parse(System.Configuration.ConfigurationManager.AppSettings["ScheduledTime"]);
    WriteToFile("Service entered " + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss:FFF tt"));
    if (DateTime.Now.ToString("MM/dd/yyyy_hh_mm") == scheduledTime.ToString("MM/dd/yyyy_hh_mm"))
    {
        WriteToFile("Service executed " + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss:FFF tt"));
        SystemReportServices.ReportServiceClient service = new SystemReportServices.ReportServiceClient();
        service.sendEmailToAdmin();
        service.sendEmailToUser();
        //ExportExcelastDay();
        //If Scheduled Time is passed set Schedule for the next day.
        scheduledTime = scheduledTime.AddDays(1);
    }

    //WriteToFile("Service executed " + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss:FFF tt"));

    TimeSpan timeSpan = scheduledTime.Subtract(DateTime.Now);
    if ((timeSpan.Days < 0 || timeSpan.Hours < 0 || timeSpan.Minutes < 0 || timeSpan.Seconds < 0))
    {
        scheduledTime = scheduledTime.AddDays(1);
        timeSpan = scheduledTime.Subtract(DateTime.Now);
    }
    string schedule = string.Format("{0} day(s) {1} hour(s) {2} minute(s) {3} seconds(s)", timeSpan.Days, timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds);

    this.WriteToFile("Simple Service scheduled to run after: " + schedule + " {0}");

    //Get the difference in Minutes between the Scheduled and Current Time.
    Int64 dueTime = Convert.ToInt64(timeSpan.TotalMilliseconds);
    this.WriteToFile("dueTime to be fired: " + dueTime + " {0}");
    //Change the Timer's Due Time.
    Schedular.Dispose();
    Schedular = new Timer(dueTime);
    Schedular.Elapsed += new ElapsedEventHandler(Elpaesdtime);
    Schedular.Enabled = true;
}

private void SchedularCallback(object e)
{
    this.WriteToFile("Simple Service Log: {0}");
    this.ScheduleService();
}

private void WriteToFile(string text)
{
    string path = @"D:\\SystemReportServicesLog\WindowsServiceLog.txt";
    using (StreamWriter writer = new StreamWriter(path, true))
    {
        writer.WriteLine(string.Format(text, DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt")));
        writer.Close();
    }
}
EN

回答 2

Stack Overflow用户

发布于 2016-08-03 16:24:22

在我的经验中,定时器总是很难让它们正确,所以我使用了一个quartz library,它可以很好地处理日程安排。

示例代码从他们的文档,您可以设置触发器,以满足您的需求。您可能想要查看更多类型的触发器。

代码语言:javascript
复制
using System;
using System.Threading;

using Quartz;
using Quartz.Impl;
using Quartz.Job;

namespace ConsoleApplication1
{
    public class Program
    {
        private static void Main(string[] args)
        {
            try
            {
                Common.Logging.LogManager.Adapter = new Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter {Level = Common.Logging.LogLevel.Info};

                // Grab the Scheduler instance from the Factory 
                IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();

                // and start it off
                scheduler.Start();

                // define the job and tie it to our HelloJob class
                IJobDetail job = JobBuilder.Create<HelloJob>()
                    .WithIdentity("job1", "group1")
                    .Build();

                // Trigger the job to run now, and then repeat every 10 seconds
                ITrigger trigger = TriggerBuilder.Create()
                    .WithIdentity("trigger1", "group1")
                    .StartNow()
                    .WithSimpleSchedule(x => x
                        .WithIntervalInSeconds(10)
                        .RepeatForever())
                    .Build();

                // Tell quartz to schedule the job using our trigger
                scheduler.ScheduleJob(job, trigger);

                // some sleep to show what's happening
                Thread.Sleep(TimeSpan.FromSeconds(60));

                // and last shut down the scheduler when you are ready to close your program
                scheduler.Shutdown();
            }
            catch (SchedulerException se)
            {
                Console.WriteLine(se);
            }

            Console.WriteLine("Press any key to close the application");
            Console.ReadKey();
        }
    }

    public class HelloJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            Console.WriteLine("Greetings from HelloJob!");
        }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2016-08-03 23:01:10

以下是托管在windows service @Devasish中的Hangfire的代码。有关在window服务中安装hangfire和设置的信息,请参阅此link。使用hangfire,你再也不用担心计时器事件了。请参见下面的示例。

代码语言:javascript
复制
using System.ServiceProcess;
using Hangfire;
using Hangfire.SqlServer;

namespace WindowsService1
{
    public partial class Service1 : ServiceBase
    {
        private BackgroundJobServer _server;

        public Service1()
        {
            InitializeComponent();
            GlobalConfiguration.Configuration.UseSqlServerStorage("connection_string");
        }

        protected override void OnStart(string[] args)
        {
            _server = new BackgroundJobServer();

            // It will run everyday at 9:00.
            RecurringJob.AddOrUpdate<EmailService>( emailService => emailService.SendEmail() , "0 9 * * *");
        }

        protected override void OnStop()
        {
            _server.Dispose();
        }
    }
}

public class EmailService
{
    public void SendEmail()
    {
        // code for sending email here
    }
}

如果你不熟悉cron expresion 0 9 * * *的时间调度,你可以查看这个link.I,希望它能对你有所帮助。:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38738055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档