Pal Sayantan Ответов: 1

Служба Windows находится в стартовом состоянии и не может сделать это в запущенном состоянии


I developed a windows service in C#. I followed some existing tutorials from google. In service.cs class the constructor is only holding the InitializeComponent() method. In OnStart() method I have written some code to open a port using TCPClient to connect via tcp connection to some other client. In that OnStart() method I am receiving a response from client using AcceptTcpClient() method and forwarding to an another class to process the client's response and send it back to the client. I maintained the coding fashion in ServiceInstaller and ServiceProcessInstaller and to start the service automatically adding up the event handler named AfterInstall and Commited. As I am installing the service, in service.msc it is showing service status as starting but the service is working as it should. Why the status is not showing running state?

Что я уже пробовал:

public partial class WinService: ServiceBase
{
      private static TCPListen listener = null;

      public Winservice()
      {
            InitializeComponent();
      }
      
      protected override void OnStart(String[] args)
      {
            loadconfig(); // Loading configuration data variables like port number IPAddress
            listener = new TcpListener(IPAddress, PortNumber);
            listener.Start();
            AnotherClass handler = new AnotherClass(listener.AcceptTcpClient);
            Thread thd = new Thread(new ThreadStart(handler.HandleSession()));
            thd.Start();
      }

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

      public loadconfig()
      { Method implementation }
}

1 Ответов

Рейтинг:
8

Jochen Arndt

TcpListener.AcceptTcpClient() это блокирующий вызов. В результате ваш OnStart() метод вернется только тогда, когда клиент подключится. Но стартовая рутина службы должна вернуться как можно скорее. Если он работает слишком долго, диспетчер управления службами перестанет ждать, пока функция вернется, оставив статус неизменным.

Решение состоит в том, чтобы выполнить вызов Accept в собственном потоке.


Pal Sayantan

Я очень новичок со всеми этими вещами. Не могли бы вы дать мне отрывок, пожалуйста? Как принять вызов внутри собственного потока.

Jochen Arndt

Вы уже создали поток. Просто передайте TcpListener своему классу вместо TcpClient, возвращаемого вызовом accept.

Основная обработка прослушивающих сокетов такая же, как и для обычных приложений, которые также должны использовать поток. Функция потока обычно представляет собой цикл while, который ожидает входящих соединений и обрабатывает их. Он должен также проверить наличие условия завершения, которое должно быть запущено в вашем случае при остановке службы (уже сделано путем остановки слушателя).

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