protected override void OnStart(string[] args)
        {
            RunningLoop = Task.Run(
                () =>
            {
                try
                {
                    bool stopping;
                    WriteInfo("Starting Actions Runner Service");
                    TimeSpan timeBetweenRetries = TimeSpan.FromSeconds(5);

                    lock (ServiceLock)
                    {
                        stopping = Stopping;
                    }

                    while (!stopping)
                    {
                        WriteInfo("Starting Actions Runner listener");
                        lock (ServiceLock)
                        {
                            RunnerListener = CreateRunnerListener();
                            RunnerListener.OutputDataReceived += RunnerListener_OutputDataReceived;
                            RunnerListener.ErrorDataReceived  += RunnerListener_ErrorDataReceived;
                            RunnerListener.Start();
                            RunnerListener.BeginOutputReadLine();
                            RunnerListener.BeginErrorReadLine();
                        }

                        RunnerListener.WaitForExit();
                        int exitCode = RunnerListener.ExitCode;

                        // exit code 0 and 1 need stop service
                        // exit code 2 and 3 need restart runner
                        switch (exitCode)
                        {
                        case 0:
                            Stopping = true;
                            WriteInfo(Resource.RunnerExitWithoutError);
                            break;

                        case 1:
                            Stopping = true;
                            WriteInfo(Resource.RunnerExitWithTerminatedError);
                            break;

                        case 2:
                            WriteInfo(Resource.RunnerExitWithError);
                            break;

                        case 3:
                            WriteInfo(Resource.RunnerUpdateInProcess);
                            var updateResult = HandleRunnerUpdate();
                            if (updateResult == RunnerUpdateResult.Succeed)
                            {
                                WriteInfo(Resource.RunnerUpdateSucceed);
                            }
                            else if (updateResult == RunnerUpdateResult.Failed)
                            {
                                WriteInfo(Resource.RunnerUpdateFailed);
                                Stopping = true;
                            }
                            else if (updateResult == RunnerUpdateResult.SucceedNeedRestart)
                            {
                                WriteInfo(Resource.RunnerUpdateRestartNeeded);
                                _restart = true;
                                ExitCode = int.MaxValue;
                                Stop();
                            }
                            break;

                        default:
                            WriteInfo(Resource.RunnerExitWithUndefinedReturnCode);
                            break;
                        }

                        if (Stopping)
                        {
                            ExitCode = exitCode;
                            Stop();
                        }
                        else
                        {
                            // wait for few seconds before restarting the process
                            Thread.Sleep(timeBetweenRetries);
                        }

                        lock (ServiceLock)
                        {
                            RunnerListener.OutputDataReceived -= RunnerListener_OutputDataReceived;
                            RunnerListener.ErrorDataReceived  -= RunnerListener_ErrorDataReceived;
                            RunnerListener.Dispose();
                            RunnerListener = null;
                            stopping       = Stopping;
                        }
                    }
                }
                catch (Exception exception)
                {
                    WriteException(exception);
                    ExitCode = 99;
                    Stop();
                }
            });
        }