C#Windows服务错误1053:服务无法及时响应启动或控制请求。 [英] C# Windows Service Error 1053: The service dis not respond to the start or control request in a timely fashion.

查看:1052
本文介绍了C#Windows服务错误1053:服务无法及时响应启动或控制请求。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在基于Windows窗体的应用程序中编写了一个窗口服务。

Windows窗体应用程序用于维护一些事件,在同一个项目中,已经编写了一个Windows服务来发送提醒电子邮件。我已经创建了一个安装程序来安装它们。我的问题是,当我在我的机器上安装并出现以下错误时,服务未启动



错误1053:服务无法响应启动或控制请求及时。





我的代码低于





I have write a window service in my Windows Form based application.
The windows form application is used to maintain some events and in same project a windows service has been written to send reminder emails. I have created a setup to install both. My problem is that the service is not started when i install in my machine and having following error

Error 1053: The service dis not respond to the start or control request in a timely fashion.


My Code is below


partial class sendAlerts : ServiceBase
    {
        private Timer Schedular;
        public sendAlerts()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            this.WriteToFile("Service started {0}");
            this.ScheduleService();
        }

        protected override void OnStop()
        {
            this.WriteToFile("Service stopped {0}");
            this.Schedular.Dispose();
        }
        public void ScheduleService()
        {
            try
            {
                Schedular = new Timer(new TimerCallback(SchedularCallback));
                string mode = ConfigurationManager.AppSettings["Mode"].ToUpper();
                this.WriteToFile("Service Mode: " + mode + " {0}");

                //Set the Default Time.
                DateTime scheduledTime = DateTime.MinValue;

                if (mode == "DAILY")
                {
                    //Get the Scheduled Time from AppSettings.
                    scheduledTime = DateTime.Parse(ConfigurationManager.AppSettings["ScheduledTime"]);
                    if (DateTime.Now > scheduledTime)
                    {
                        //If Scheduled Time is passed set Schedule for the next day.
                        scheduledTime = scheduledTime.AddDays(1);
                    }
                }

                if (mode.ToUpper() == "INTERVAL")
                {
                    //Get the Interval in Minutes from AppSettings.
                    int intervalMinutes = Convert.ToInt32(ConfigurationManager.AppSettings["IntervalMinutes"]);

                    //Set the Scheduled Time by adding the Interval to Current Time.
                    scheduledTime = DateTime.Now.AddMinutes(intervalMinutes);
                    if (DateTime.Now > scheduledTime)
                    {
                        //If Scheduled Time is passed set Schedule for the next Interval.
                        scheduledTime = scheduledTime.AddMinutes(intervalMinutes);
                    }
                }

                TimeSpan 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.
                int dueTime = Convert.ToInt32(timeSpan.TotalMilliseconds);

                //Change the Timer's Due Time.
                Schedular.Change(dueTime, Timeout.Infinite);
            }
            catch (Exception ex)
            {
                WriteToFile("Error found to send reminder on: {0} " + ex.Message + ex.StackTrace);

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

        private void SchedularCallback(object e)
        {
            try
            {
                DataSet ds = new DataSet();
                ds.ReadXml(Environment.CurrentDirectory + @"\App_Data\userCredentials.xml");
                if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                {
                    foreach (DataRow dr in ds.Tables[0].Rows)
                    {
                        string name = Convert.ToString(dr["user"]);
                        string email = Convert.ToString(dr["emailID"]);
                        WriteToFile("Trying to send remainder to: " + name + " " + email);
                        using (MailMessage mm = new MailMessage(ConfigurationManager.AppSettings["FromMail"].ToString(), email))
                        {
                            mm.Subject = ConfigurationManager.AppSettings["emailSubject"].ToString();
                            mm.Body = string.Format("<b">
                            mm.IsBodyHtml = true;
                            SmtpClient smtp = new SmtpClient();
                            smtp.Host = ConfigurationManager.AppSettings["host"].ToString();
                            smtp.EnableSsl = true;
                            System.Net.NetworkCredential credentials = new System.Net.NetworkCredential();
                            credentials.UserName = ConfigurationManager.AppSettings["FromMail"].ToString();
                            credentials.Password = ConfigurationManager.AppSettings["password"].ToString();
                            smtp.UseDefaultCredentials = true;
                            smtp.Credentials = credentials;
                            smtp.Port = 587;
                            smtp.Send(mm);
                            WriteToFile("Email sent successfully to: " + name + " " + email);
                        }
                    }
                }
                this.ScheduleService();
            }
            catch (Exception ex)
            {
                WriteToFile("Error found to send reminder on: {0} " + ex.Message + ex.StackTrace);

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

        private void WriteToFile(string text)
        {
            //AppDomain.CurrentDomain.BaseDirectory + @"\App_Data\log.txt";
            string path = Environment.CurrentDirectory + @"\App_Data\serviceLogs.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();
            //}
        }
    }

推荐答案

不建议在服务 OnStart()事件中编写任何业务逻辑。让服务以最短的时间顺利开始。它提供更好的用户体验。如果您在 OnStart()中写入任何逻辑,那么该服务将处于开始状态,直到执行完成。

您可以做的是将所有逻辑移动到单独的方法中。然后通过传递使用新创建的方法创建的 ThreadStart 对象来创建线程

It is not recomended to write any business logic inside the service OnStart() event. Let the service start smoothly with minimum required time. It gives better user experience. If you write any logic inside OnStart() then the service will be in "Starting" state untill the execution finished.
What you can do is move all of your logic into a separate method. Then create a Thread by passing a ThreadStart object created with the newly created method.
//include namespace
using System.Threading;

//extract business logic to a new method
private void ExecuteMyBusiness()
{
   this.WriteToFile("Service started {0}");
   this.ScheduleService();
}

//your changed OnStart() event
protected override void OnStart(string[] args)
{
   Thread myBusinessThread = new Thread(new ThreadStart(ExecuteMyBusiness));
   myBusinessThread.Start();
}





你可以尝试一下,如果它工作正常那么好又好。

但是,这不是全部。你需要检查 OnStop(),如果线程还没有完成分配给它的任务的执行,那么它应该等待它完成。

为此目的,您需要加入以下更改 -



You can give this a try and if it works fine then well and good.
But, this is not all. You need to check in OnStop() for if the thread has not finished the execution of the task assigned to it then it should wait for it to complete.
For that purpose, you need to incorporate following changes-

//declare a global variable to keep track of thead execution status
private bool isThreadRunning= false;

//change the flag as per execution status
private void ExecuteMyBusiness()
{
   isThreadRunning=true;
   this.WriteToFile("Service started {0}");
   this.ScheduleService();
   isThreadRunning=false;
}

//change your OnStop() accordingly
protected override void OnStop()
{
   while(isThreadRunning)
   {
      Thread.Sleep(1000); //wait for 1 second and then try again
   }
   this.WriteToFile("Service stopped {0}");
   this.Schedular.Dispose();
}





好​​的。这就是全部吗?

不,但它应解决您当前的问题。你需要做各种验证,但这应该是一个很好的开始。



希望,它有帮助:)

请让我知道,如果您在实施此设计时遇到任何问题或疑问。



Ok. Is that all?
No, but it should resolve your current problem. You need to do various validation but this should be a good approach to start with.

Hopefully, it helps :)
Please let me know, if you have questions or problem in implementing this design.


这篇关于C#Windows服务错误1053:服务无法及时响应启动或控制请求。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆