Служба Windows C # - запускается, а затем автоматически останавливается - PullRequest
5 голосов
/ 10 сентября 2011

Я создаю эту службу Windows, следуя инструкциям на Пошаговое руководство по MSDN: Создание службы Windows , и после успешной установки я захожу в Services.msc, чтобы запустить службу Windows, и до ее завершения я запускаю. получить следующее сообщение:

Служба EIWindowsService на локальном компьютере запускается, а затем останавливается. Некоторые службы автоматически останавливаются, если они не используются другими службами или программами.

Я знаю, что служба Windows запускается нормально, потому что в файле журнала есть запись о том, что служба запущена. Я провел некоторое исследование, прежде чем опубликовать здесь, и в ответе Некоторые службы автоматически останавливаются говорится, что проблема может заключаться либо в том, что метод OnStart выдает ошибку, либо в том, что OnStart не запускает поток. Поэтому я изменил свой код так, что единственное, что есть в OnStart - это запуск двух таймеров и запись в журнале, поэтому не нужно обрабатывать исключения. Я также добавил поток, чтобы «перейти» к другому методу.

Я снова попробовал службу Windows, и я знаю, что она «перешла» на новый метод, на который указывал поток, потому что у меня там была запись в журнале, которая выдавала ошибку aFormatException из-за некоторого преобразования, которое я делал. Я прокомментировал преобразование, и служба Windows все еще только начинала запускаться, а затем автоматически останавливалась.

Дальнейшие исследования показали мне, что мне может понадобиться цикл, чтобы сохранить обработку в методе, поэтому я взял информацию из C - Служба Windows Service на и настроил бесконечный цикл while. Я также обнаружил, что может происходить сборка мусора, и установил оператор KeepAlive для таймеров, как предложено в разделе «Примеры» Класс таймера MSDN . Все те же проблемы.

В этот момент я чувствую, что исчерпал все исследования, которые могу сделать, поэтому было бы целесообразно опубликовать мой вопрос здесь. Весь мой код приведен ниже, и я отмечу, что перед внесением каких-либо изменений я удалил службу Windows, удалил проект установки и удалил установщики из кода C #. Затем я внес изменения и снова начал с инструкций, описанных в пошаговом руководстве, начиная с того момента, когда в нем приведены инструкции по установке установщиков. Я делал это каждый раз, потому что обнаружил, что если я внес изменения и не удалил службу Windows, удалил проект установки и удалил установщики, то мои изменения не вступят в силу для установленной в настоящее время службы Windows.

Буду признателен за любую помощь, которую вы можете оказать. Я буду здесь еще 15 минут, а потом завтра проверю.

SERVICE1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;

namespace EIWindowsService
{
    public partial class Service1 : ServiceBase
    {
        Logs.ErrorLog logFile = new Logs.ErrorLog();
        private System.Threading.Thread onStartThread;

        public Service1()
        {
            InitializeComponent();            
        }

        protected override void OnStart(string[] args)
        {
            try
            {
                iTimer.Start();
                iTimer.Elapsed += new ElapsedEventHandler(iTimer_Elapsed);
                pTimer.Start();
                pTimer.Elapsed += new ElapsedEventHandler(pTimer_Elapsed);                
                onStartThread = new System.Threading.Thread(TimerValue);
                onStartThread.Start();
                logFile.SendToLog("EIWindows Service started on " + GetDate());
            }
            catch (ArgumentOutOfRangeException ex)
            {
                logFile.SendToLog("ArgumentOutOfRangeException", "EIWindowsService\\Service1.cs", "OnStart()", ex);
            } //end of ArgumentOutOfRangeException CATCH statement
        }

        protected override void OnStop()
        {
            iTimer.Stop();
            pTimer.Stop();
            logFile.SendToLog("EIWindowsService\\Service1.cs", "OnStop()", "EIWindows Service stopped on " + GetDate());

        }

        private void TimerValue()
        {
            try
            {
                   /*commented out because it was throwing an exception error*/
                   //double iTimerValue = Convert.ToDouble(iTimer.ToString());
                   //double pTimerValue = Convert.ToDouble(pTimer.ToString());
                while (1 > 0)
                {
                       //if (iTimerValue % 1800000 == 0)  //if the timer hits the 30min mark
                       //{
                       //    logFile.SendToLog("Current iTimer Value = " + iTimerValue.ToString());
                       //}
                       //if (pTimerValue % 1800000 == 0)  //if the timer hits the 30min mark
                       //{
                       //    logFile.SendToLog("Current pTimer Value = " + pTimerValue.ToString());
                       //}
                    GC.KeepAlive(iTimer);
                    GC.KeepAlive(pTimer);
                }
                   //TimerValue();
            }
            catch (OverflowException ex)
            {
                logFile.SendToLog("OverflowException", "EIWindowsService\\Service1.cs", "TimerValue()", ex);
            } //end of OverflowException CATCH statement
            catch (ArgumentException ex)
            {
                logFile.SendToLog("ArgumentException", "EIWindowsService\\Service1.cs", "TimerValue()", ex);
            } //end of ArgumentException CATCH statement
            catch (FormatException ex)
            {
                logFile.SendToLog("FormatException", "EIWindowsService\\Service1.cs", "TimerValue()", ex);
            } //end of FormatException CATCH statement
        }

        private string GetDate()
        {
            string current = "No Date Recorded";
            try
            {
                current = DateTime.Now.ToString("F");
            }
            catch (FormatException ex)
            {
                logFile.SendToLog("FormatException", "EIWindowsService\\Service1.cs", "GetDate()", ex);
            } //end of FormatException CATCH statement

            return current;
        } //end of method GetDate

        private void iTimer_Elapsed(object source, ElapsedEventArgs e)
        {
            try
            {
                iTimer.Stop();
                ImportI();
                iTimer.Start();
            }
            catch (ArgumentOutOfRangeException ex)
            {
                logFile.SendToLog("ArgumentOutOfRangeException", "EIWindowsService\\Service1.cs", "iTimer_Elapsed()", ex);
            } //end of ArgumentOutOfRangeException CATCH statement
        } //end of method iTimer_Elapsed

        private void pTimer_Elapsed(object source, ElapsedEventArgs e)
        {
            try
            {
                pTimer.Stop();
                ImportP();
                pTimer.Start();
            }
            catch (ArgumentOutOfRangeException ex)
            {
                logFile.SendToLog("ArgumentOutOfRangeException", "EIWindowsService\\Service1.cs", "pTimer_Elapsed()", ex);
            } //end of ArgumentOutOfRangeException CATCH statement
        } //end of method pTimer_Elapsed

        private void ImportI()
        {
            //does some action but commented out because it never gets here and is not relavant to this question.
        } //end of method ImportI

        private void ImportP()
        {
            //does some action but commented out because it never gets here and is not relavant to this question.
        } //end of method ImportP
    }
}

SERVICE1.DESIGNER.CS (соответствующий материал)

private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.pTimer = new System.Timers.Timer(10800000);  //3hrs
            this.iTimer = new System.Timers.Timer(3600000);  //1hr
            // 
            // pTimer
            // 
            this.pTimer.Enabled = true;
            // 
            // iTimer
            // 
            this.iTimer.Enabled = true;
            // 
            // Service1
            // 
            this.ServiceName = "EIWindowsService";

        }

        #endregion

        private System.Timers.Timer pTimer;
        private System.Timers.Timer iTimer;

Ответы [ 2 ]

2 голосов
/ 10 сентября 2011

Вам не нужно создавать отдельный поток или беспокоиться о сборщике мусора.Каркас обрабатывает все это для вас.Просто создайте таймеры, и они будут называться.Вот пример.

public partial class Service1 : ServiceBase
{
    private Timer timer;

    public Service1()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        timer = new Timer(1000);
        timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        timer.Start();
    }

    void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        using (StreamWriter writer = File.AppendText(@"C:\Users\alfonso\Desktop\log.txt"))
        {
            writer.WriteLine(string.Format("{0} : {1}", DateTime.Now, "Logging from the service"));
        }
    }

    protected override void OnStop()
    {
    }
}
0 голосов
/ 27 ноября 2012

Что-то еще, что может помочь кому-то натолкнуться на этот пост и вышеупомянутые решения не работают. Когда у меня возникла эта проблема, я добавил это в конфигурацию моей службы Windows:

<system.web>
    <compilation debug ="true" />    
</system.web>

Я добавил это, чтобы можно было присоединить отладчик к службе при его локальном запуске, однако при попытке переместить службу на другой сервер она выдала указанную ошибку. Удалив это из конфига, сервис снова заработал.

...