C # Служба Windows: служба не отвечает на запуск - PullRequest
0 голосов
/ 20 июля 2011

Это моя первая попытка создания службы Windows, которая вызывает несколько потоков.Я создал консольное приложение, затем добавил службу Windows и установщик.Мой код ниже.

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

    protected override void OnStart(string[] args)
    {
        System.Timers.Timer timer1 = new System.Timers.Timer();
        timer1.Interval = 10000;
        timer1.Start();
        timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
    }

    public static void timer1_Elapsed(object sender, EventArgs e)
    {
        Program.ThreadController();   
    }

    protected override void OnStop()
    {
        // TODO: Add code here to perform any tear-down necessary to stop your service.
    }
}

class Program
{
    static void Main(string[] args)
    {
        ThreadController();
    }

    public static void ThreadController()
    {
        for (int i = 0; i < 3; i++)
        {
            new Thread(() => { processEventLogTesting(); });
        }
    }

    public static void processEventLogTesting()
    {
        EventLog.WriteEntry("ProcessThread1", "Process1 Works");
    }
}

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

Спасибо.

Ответы [ 5 ]

4 голосов
/ 20 июля 2011

У вас есть бесконечная рекурсия в processEventLogTesting ().Вот почему он не отвечает.Когда я пишу службу Windows с таймером, все, что я делаю, это подключаюсь к обратному вызову и запускаю таймер в OnStart.Тогда я сижу и позволяю ему делать свое дело.Вы пытаетесь сделать слишком много при запуске.

1 голос
/ 21 июля 2011

Сначала я бы добавил некоторые возможности для отладки. Это на самом деле легко (когда ты умеешь !!!).

Добавьте это к вашему классу:

[DllImport("kernel32.dll")]
public static extern Int32 AllocConsole();

Затем добавьте это в свою основную функцию (и вы МОЖЕТЕ сделать это тоже при работе в качестве службы, если вы разрешаете службе доступ к пользовательскому интерфейсу).

for (int loop = 0; loop < args.Count; loop++)
{
  if (args[loop] == "debug")
    AllocConsole();
}

Это дает вам консольное окно, и вы можете использовать Console.WriteLine для отправки вывода на него сейчас. Yummy.

Теперь вы хотите, чтобы диспетчер управления службами вызвал ваш метод OnStart, а затем этот метод должен ВЕРНУТЬ сигнал OK, чтобы SCM узнал, что ваше приложение запущено нормально. В противном случае SCM считает, что что-то не так, и убивает ваше приложение. Так что OnStart должен запускать ваши темы. Итак, создайте метод Run (), который будет запускаться вашим потоком (и Main), и заставить OnStart возвращать как можно быстрее.

Я заметил, что ничего не вижу в вашем примере кода:

System.ServiceProcess.ServiceBase [] ServicesToRun; ServicesToRun = new System.ServiceProcess.ServiceBase [] {new WinService1 ()}; System.ServiceProcess.ServiceBase.Run (ServicesToRun);

Я подозреваю, что ваше приложение не сообщает SCM, что оно успешно запустило "службу", которая находится внутри вашего исполняемого файла.

Вы хотите, чтобы ваше приложение запустилось, передайте «службу» SCM и сообщите, что с вами все в порядке, а затем вернитесь, пока ваша служба теперь работает со своим собственным потоком.

См. Эту статью для большой прогулки по: http://msdn.microsoft.com/en-us/library/aa984464(v=vs.71).aspx

0 голосов
/ 20 июля 2011
  1. Вы не запускаете потоки в своем коде, поэтому:

    for (int i = 0; i < 3; i++)
    {
        new Thread(() => { processEventLogTesting(); }) { IsBackground = true }.Start();
    }
    
  2. На вашем processEventLogTesting() в дополнение к неправильному рекурсивному вызову вы создаете таймер, а затем просто переопределяете его на timer1 = new System.Timers.Timer();, чтобы он не срабатывал.

    public static void processEventLogTesting()
    {
        System.Timers.Timer timer1 = new System.Timers.Timer();
        timer1.Interval = 10000;
        timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
        timer1.Start();
    }
    
0 голосов
/ 20 июля 2011
 partial class Service1 : ServiceBase
 {
    private Program program;

    public Service1()
    {
        InitializeComponent();
        program = new Program ();
    }

    protected override void OnStart(string[] args)
    {
        program.Start ();
    }

    protected override void OnStop()
    {
        program.Stop ();
    }
}

class Program
{
    private Systems.Timers.Timer timer;

    public Program ()
    {
        timer = new System.Timers.Timer ();
        timer.Interval = 10000;
        timer.Elapsed += new ElapsedEventHandler (timer_Elapsed);

    }

    public void Start () 
    {
        timer.Enabled = true;
    }

    public void Stop ()
    {
        timer.Enabled = false;
    }

    public static void timer_Elapsed (object sender, EventArgs e)
    {
        EventLog.WriteEntry ("ProcessThread1", "Process1 Works");
    }
}
0 голосов
/ 20 июля 2011

Службы Windows, как известно, сложно отлаживать. Если вы не получаете никаких других сообщений, попробуйте поставить на паузу паузу, и вы сможете подключиться к ней, а затем посмотрите, в чем проблема.

У Nik есть ответ, но это может быть полезно для других служб Windows!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...