窗口服务没有定期运行 [英] windows service doesn't run at regular intervals

查看:94
本文介绍了窗口服务没有定期运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经开发了窗口服务检查一些服务运行与否,每两个minutes.if服务未运行则自动启动它们。

I have developed windows service for checking some services running or not for every two minutes.if the services are not running then start them automatically.

下面是我的代码

public partial class Service1 : ServiceBase
    {
        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {

            this.CheckServices();

            this.ScheduleService();


        }

        protected override void OnStop()
        {
            this.Schedular.Dispose();
        }




        public void CheckServices()
        {

            log4net.Config.BasicConfigurator.Configure();
            log4net.ILog log = log4net.LogManager.GetLogger(typeof(Service1));
            try
            {

                string[] arr1 = new string[] { "CaseWorksCachingService", "Te.Service" };
                for (int i = 0; i < arr1.Length; i++)
                {
                    ServiceController service = new ServiceController(arr1[i]);

                    service.Refresh();

                    if (service.Status == ServiceControllerStatus.Stopped)
                    {
                        service.Start();

                    }
                }


            }
            catch (Exception ex)
            {
                log.Error("Error Message: " + ex.Message.ToString(), ex);
            }


        }

        //ScheduleService Method

        private Timer Schedular;


        public void ScheduleService()
        {
            try
            {
                Schedular = new Timer(new TimerCallback(SchedularCallback));
                string mode = ConfigurationManager.AppSettings["Mode"].ToUpper();


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



                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);


                //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)
            {


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

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

和这里是我的app.config文件

and here is my app.config file

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key ="Mode" value ="Interval"/>
    <!-- <add key ="Mode" value ="Interval"/>-->
    <add key ="IntervalMinutes" value ="2"/>

  </appSettings>

  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=2.0.5, Culture=neutral, PublicKeyToken=1b44e1d426115821" />
  </configSections>
  <!-- Log4net Logging Setup -->
  <log4net>
    <appender name="FileAppender" type="log4net.Appender.FileAppender,log4net">
      <file value="C:\\mylogfile1.txt" />
      <!-- the location where the log file would be created -->
      <appendToFile value="true" />
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
      </layout>
      <filter type="log4net.Filter.LevelRangeFilter">
        <levelMin value="INFO" />
        <levelMax value="FATAL" />
      </filter>
    </appender>
    <root>
      <level value="DEBUG" />
      <appender-ref ref="FileAppender" />
    </root>
  </log4net>
</configuration>



错误:本地计算机上的Windows搜索服务启动,然后停止一些服务,如果他们自动停止不是由其他服务或程序使用

Error: "The Windows Search service on local computer started and then stopped. Some services stop automatically if they are not in use by other services or programs"

推荐答案

与您服务到底是什么问题马特·戴维斯说,在他的回答:服务将只停留在运行,如果在的OnStart 催生了前台线程。这就是他的代码正在做什么。它只是创建一个线程,做基本上只是等待,但是这足以让服务运行。

The problem with your service is exactly what Matt Davis says in his answer: A service will only stay running if there is a foreground thread spawned in OnStart. This is what his code is doing. It just creates a thread that does basically nothing but wait, but that's enough to keep the service running.

你的代码可以从一件事保持不变,除了各地。更改 ScheduleService 方法如下:

The rest of your code can stay the same, apart from one thing. Change your ScheduleService method as follows:

   public void ScheduleService()
    {
        try
        {
            // Only create timer once
            if (Schedular != null)
                Schedular = new Timer(new TimerCallback(SchedularCallback));

            // Use proper way to get setting
            string mode = Properties.Settings.Default.Mode.ToUpper();

            ...

            if (mode == "INTERVAL")
            {
                // Use proper way to get settings
                int intervalMinutes = Properties.Settings.Default.IntervalMinutes;

                ...






我知道有些人可能不认为这是一个答案,但调试似乎这里是关键,因此我要告诉你我找到了一个简单的方法来调试服务。


I know that some people may not consider this an answer, but debugging seems to be the key here and thus I'm going to tell you what I found an easy way to debug a service.

第1步结果
两种方法扩展您的服务:一个叫的OnStart 和一个叫调用OnStop ,作为默认的方法得到保护。

Step 1
Extend your service with two methods: One to call OnStart and one to call OnStop, as the default methods are protected.

public void DoStart(string[] args)
{
    OnStart(xyz);
}

public void DoStop()
{
    OnStop();
}



第2步结果
添加一个简单的GUI。没有任何控制一个WinForms形式是不够的。扩展构造函数把你的服务类的一个实例。当窗体加载启动服务,它关闭时,停止服务。这取决于你如何创建表单,你可能需要手动引用 System.Windows.Forms的 System.Drawing中中。您的项目

例如:

public class ServiceGUI : System.Windows.Forms.Form
{
    private MyService _myService;

    public ServiceGUI(MyService service)
    {
        _myService = service;
    }

    protected override void OnShown(EventArgs e)
    {
        base.OnShown(e);
        _myService.DoStart(null);
    }

    protected override void OnClosing(CancelEventArgs e)
    {
        base.OnClosing(e);
        _myService.DoStop();
    }        
}



第3步

让你的方法决定是否作为一种服务或一​​个GUI应用程序运行。方便易用的 Environment.UserInteractive 属性允许你决定的EXE是否被一些GUI用户运行。

Step 3
Let your Main method decide whether to run as a service or as a GUI application. The handy Environment.UserInteractive property allows you do decide whether the exe was run by some GUI user.

if (Environment.UserInteractive)
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new ServiceGUI(new MyService()));
}
else
{
    ServiceBase.Run(new ServiceBase[] { new MyService() });
}



你能怎么做呢?结果
你就可以开始你的应用程序,就好像它是一个正常的应用程序,实际上正确调试,设置断点,检查变量等。当然,我知道,你还可以将调试器附加到正在运行的进程,但在你的情况下,你不'T有一个正在运行的进程,所以这是一个很好的解决方案,看看是什么问题。

What can you do now?
You can start your application as if it were a normal application and actually properly debug, setting breakpoints, inspecting variables etc. Of course I know that you can also attach your debugger to a running process, but in your case you don't have a running process, so this is a good solution to see what the problem is.

之类的东西你服务启动的代码可能无法正常工作(除非你运行Visual Studio以管理员身份),但在开始你的服务时,也可以是一个很好的测试情况是否正常工作遇到错误。

Things like your service starting code will probably not work (unless you run Visual Studio as administrator), but that can also be a nice test whether things work when starting your services runs into an error.

这篇关于窗口服务没有定期运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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