C# Windows服务不断启动和停止

C# Windows服务不断启动和停止,c#,windows-services,C#,Windows Services,启动Windows服务时不断遇到此错误消息 本地计算机上的服务已启动,然后停止。如果某些服务未被其他服务和程序使用,它们将自动停止 我的代码: protected override void OnStart(string[] args) { string eventLogMessage = string.Format(@"Notify Service is starting :{0}", DateTime.Now); EventLogging.

启动Windows服务时不断遇到此错误消息

本地计算机上的服务已启动,然后停止。如果某些服务未被其他服务和程序使用,它们将自动停止

我的代码:

     protected override void OnStart(string[] args)
     {
        string eventLogMessage = string.Format(@"Notify Service is starting :{0}", DateTime.Now);
        EventLogging.LogInformation(eventLogMessage);

            double interval;

            try
            {
                interval = Convert.ToDouble(ConfigurationManager.AppSettings["intervalInSeconds"]);
                EventLogging.LogInformation(
                    string.Format("Loaded configuration: Interval duration is {0} minutes", (interval / 60)));
            }
            catch (Exception exception)
            {
                interval = 3600;

                eventLogMessage = string.Format("Loading configuration failed: Interval duration is {0} minutes", (interval / 60));
                eventLogMessage += string.Format("\nMessage was: {0}", exception.Message);

                EventLogging.LogWarning(eventLogMessage);
            }

            interval = interval * 1000;

            _timer.Interval = interval;
            _timer.Elapsed += TimerTick;
            _timer.Start();

            eventLogMessage = string.Format(@"Notify service has started: {0}", DateTime.Now);
            EventLogging.LogInformation(eventLogMessage);

            var workerThread = new Thread(NotifyUsers) { IsBackground = true };
            workerThread.Start();

    }

    private void NotifyUsers()
    {
        var userBL = new UserBL();

        List<User> usersToBeMailed = userBL.GetAllUsersWhosePasswordsWillExpire();

        string eventLogMessage = string.Format("Number of users to be mailed is {0}", usersToBeMailed.Count);
        EventLogging.LogInformation(eventLogMessage);

        foreach (User user in usersToBeMailed)
        {
            userBL.MailUser(user);
        }
    }

    private void TimerTick(object sender, ElapsedEventArgs e)
    {
        var workerThread = new Thread(NotifyUsers) { IsBackground = true };
        workerThread.Start();
    }

    protected override void OnStop()
    {
        base.OnStop();

        string eventLogMessage = @"Password notify service has stopped: " + DateTime.Now;

        EventLogging.LogInformation(eventLogMessage);
    }


    protected override void OnPause()
    {
        base.OnPause();
        _timer.Stop();
        EventLogging.LogWarning("Paused");
    }

    protected override void OnContinue()
    {
        base.OnContinue();
        _timer.Start();
        EventLogging.LogInformation("Resumed");
    }
}
protected override void OnStart(字符串[]args)
{
string eventLogMessage=string.Format(@“通知服务正在启动:{0}”,DateTime.Now);
登录信息(eventLogMessage);
双间隔;
尝试
{
间隔=Convert.ToDouble(ConfigurationManager.AppSettings[“intervalInSeconds”]);
EventLogging.LogInformation(
Format(“加载的配置:间隔持续时间为{0}分钟”(Interval/60));
}
捕获(异常)
{
间隔=3600;
eventLogMessage=string.Format(“加载配置失败:间隔持续时间为{0}分钟”(Interval/60));
eventLogMessage+=string.Format(“\n消息为:{0}”,exception.Message);
日志警告(eventLogMessage);
}
间隔=间隔*1000;
_计时器。间隔=间隔;
_timer.appeated+=TimerTick;
_timer.Start();
eventLogMessage=string.Format(@“通知服务已启动:{0}”,DateTime.Now);
登录信息(eventLogMessage);
var workerThread=new Thread(NotifyUsers){IsBackground=true};
workerThread.Start();
}
私有用户()
{
var userBL=new userBL();
List usersToBeMailed=userBL.GetAllUsersWhosePasswordsWillExpire();
string eventLogMessage=string.Format(“要发送邮件的用户数为{0}”,usersToBeMailed.Count);
登录信息(eventLogMessage);
foreach(usersToBeMailed中的用户)
{
userBL.MailUser(用户);
}
}
私有void TimerTick(对象发送方,ElapsedEventArgs e)
{
var workerThread=new Thread(NotifyUsers){IsBackground=true};
workerThread.Start();
}
受保护的覆盖void OnStop()
{
base.OnStop();
字符串eventLogMessage=@“密码通知服务已停止:”+DateTime.Now;
登录信息(eventLogMessage);
}
受保护的覆盖void OnPause()
{
base.OnPause();
_timer.Stop();
EventLogging.LogWarning(“暂停”);
}
受保护的覆盖无效OnContinue()
{
base.OnContinue();
_timer.Start();
事件日志记录。登录信息(“恢复”);
}
}

您必须让至少一个线程执行某些操作,而不是作为后台线程,才能使进程保持活动状态。运行
OnStart
代码的线程实际上不是您的线程之一,此外,您必须从
OnStart
返回才能被视为已成功启动

这可能非常简单,只需从
OnStart
方法创建并运行一个新的
线程,该线程只需等待
ManualResetEvent
对象,然后从
OnStop
代码中设置


P>可选地,为这个线程找到一些有用的工作要做(但仍然使用事件对象在它应该关闭的时候发出信号),或者另一个选择是——考虑这个代码是否属于服务。如果它只是周期性地唤醒以通知用户,为什么不使用计划任务呢?

OnStart
`OnStop`方法中有相当严格的规则。我猜是
workerThread
代码。作为一个测试,尝试删除它,看看它是否仍然停止。同时将_计时器和工作程序移动到一个单独的“初始化”方法。
OnStart
应该很简单,可以进行完整的异常处理。尝试将调试器附加到服务以查找异常发生的位置,在OnStart()方法的第一行添加Thread.Sleep(30000),以便在代码完成执行之前有时间附加调试器。不要忘记Thread.Sleep调用后的断点,这样当线程唤醒时,您可以手动逐行调试。您可以在windows日志中找到一些有用的信息。在事件查看器上打开MMC,导航到Windows日志->应用程序。通常您会在那里发现一些抛出的异常。