Я создал службу Windows, которая «работает», но зависает при запуске

#c# #windows-services

#c# #windows-services

Вопрос:

Итак, некоторое время назад я создал службу Windows, которая считывает последовательный порт и в зависимости от возвращаемого значения изменяет системный объем. Проблема в том, что когда я запускаю службу, она зависает в режиме запуска, но все еще делает то, что должна делать. но она не будет работать, если вы настроили ее на автоматический запуск при запуске. Я впервые создаю службу Windows, поэтому с ней может возникнуть много проблем.

вот запущенный код:

 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.Threading.Tasks;
using AudioSwitcher.AudioApi.CoreAudio;
using System.IO.Ports;
using System.Threading;

namespace audio_controller_WS
{
    public partial class AudioContorllerWS : ServiceBase
    {
        static bool _continue;
        static SerialPort _serialPort;
        public AudioContorllerWS()
        {
            InitializeComponent();

           


        }
        public static void Read()
        {
            CoreAudioDevice defaultPlaybackDevice = new CoreAudioController().DefaultPlaybackDevice;
            while (_continue)
            {
                try
                {
                    String message = _serialPort.ReadLine();
                    int convert = int.Parse(message);
                    defaultPlaybackDevice.Volume = convert;
                }
                catch (Exception)
                { }

            }
        }
        protected override void OnStart(string[] args)
        {
                      // string message;
            StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
            Thread readThread = new Thread(Read);

            // Create a new SerialPort object with default settings.
            _serialPort = new SerialPort();

            // Allow the user to set the appropriate properties.
            _serialPort.PortName = "COM10";
            _serialPort.BaudRate = 9600;
            _serialPort.DataBits = 8;
            // Set the read/write timeouts
            _serialPort.ReadTimeout = 500;
            _serialPort.WriteTimeout = 500;

            _serialPort.Open();
            _continue = true;
            readThread.Start();
            readThread.Join();
            _serialPort.Close();

        }
        protected override  void OnContinue()
        {

        }


        protected override void OnStop()
        {
        }
    }
}


  

Я знаю, что мой код не должен запускаться при запуске, но иначе я не работаю.

Комментарии:

1. Показывает ли она какое-либо сообщение при запуске службы?

2. Да, там написано «ошибка: 1053: служба неправильно ответила на команду запуска», что-то в этом роде, но это потому, что весь мой код находится в части «при запуске». но это своего рода проблема, если бы я вставил все в continue, у нее не было бы никаких ошибок, но она просто не делала бы ничего, что должна была. Она работает в фоновом режиме, но когда я отправляю сигнал, она ничего не делает.

3. Где вы устанавливаете _continue в false для выхода из цикла чтения? Кроме того, вам, вероятно, не следует присоединяться к потоку чтения при запуске. Служба остается в начальном состоянии до завершения работы этого метода. Служба продолжит работу после того, как метод будет создан, так что вы можете позволить потоку чтения выполняться в фоновом режиме.

4. Попробуйте обернуть код в метод onstart в новой задаче и сообщите мне о результатах.

Ответ №1:

Вам нужно разрешить методу OnStart завершить работу. Попробуйте это:

 public partial class AudioContorllerWS : ServiceBase
{
    static bool _continue;
    static SerialPort _serialPort;
    static Thread readThread;
    
    public AudioContorllerWS()
    {
        InitializeComponent();         
    }
    
    public static void Read()
    {
        CoreAudioDevice defaultPlaybackDevice = new CoreAudioController().DefaultPlaybackDevice;
        while (_continue)
        {
            try
            {
                String message = _serialPort.ReadLine();
                int convert = int.Parse(message);
                defaultPlaybackDevice.Volume = convert;
            }
            catch (Exception)
            { }
        }
    }
    
    protected override void OnStart(string[] args)
    {
        // string message;
        StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
        readThread = new Thread(Read);

        // Create a new SerialPort object with default settings.
        _serialPort = new SerialPort();

        // Allow the user to set the appropriate properties.
        _serialPort.PortName = "COM10";
        _serialPort.BaudRate = 9600;
        _serialPort.DataBits = 8;
        // Set the read/write timeouts
        _serialPort.ReadTimeout = 500;
        _serialPort.WriteTimeout = 500;

        _serialPort.Open();
        _continue = true;
        readThread.Start();
        // don't join
    }

    protected override  void OnContinue()
    {
    }


    protected override void OnStop()
    {
        _continue = false;
        readThread.Join(timeout);
        _serialPort.Close();
        // abort it if it hasn't exited
    }
}
  

Комментарии:

1. Спасибо, что это сработало, единственное, что мне пришлось изменить, это переместить _serialport.close() также в onStop.