【问题标题】:Windows Service installed. But start, stop buttons disabled [duplicate]已安装 Windows 服务。但是开始,停止按钮被禁用[重复]
【发布时间】:2016-02-08 11:12:34
【问题描述】:

我创建了 Windows 服务。 Installutil.exe 安装成功,但是当我按下开始按钮时出现进度条“正在启动”,然后它停止在 50%。我必须取消。取消服务后完美运行,但禁用启动、停止和暂停命令。如果我想停止服务,我必须卸载服务。可能是什么原因?

主要方法:

static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
            { 
                new TelegramBotService()
            };
        ServiceBase.Run(ServicesToRun);
    }

这是我的服务类:

partial class TelegramBotService : ServiceBase
{
    private static Logger logger = LogManager.GetCurrentClassLogger();
    public TelegramBotService()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        try
        {
            RunBot().Wait();
            logger.Info("Start windows service");
        }
        catch(Exception ex)
        {
            logger.Error(ex.Message);
        }
    }

    private async Task RunBot()
    {
        try
        {

          logger.Info("Start Telegram Bot");
          //var ElectionsBot = new ElectionsInfo();
          var ElectionsBot = new ElectionsCount();
          await ElectionsBot.Start();
        }
        catch(Exception ex)
        {
            logger.Error(ex.Message);
        }
    }

    protected override void OnStop()
    {
        logger.Info("Stop windows service");
    }
}

【问题讨论】:

标签: c# windows-services


【解决方案1】:

OnStart 方法必须在 10 秒内完成,否则服务控制管理器会认为它已挂起。目前它无限期地等待 RunBot 任务完成。

我描述了一个good way to deal with this approach。这是我的 OnStart 方法,它启动服务的控制器线程:

// SCM requests service start using its own thread.
// This method must complete within 10 seconds of it
// starting. Otherwise the SCM diagnoses a hang.
protected override void OnStart(string[] args)
{
    AppDomain currentDomain = AppDomain.CurrentDomain;
    currentDomain.UnhandledException += new UnhandledExceptionEventHandler(this.UnhandledExceptionFilter);

    this.ThreadController = new Thread(new ThreadStart(ControllerThreadRunning));
    this.ThreadController.Name = THREAD_NAME_CONTROLLER;
    this.ThreadController.Start();
    base.OnStart(args);
}

这是控制器线程:

// Invoked when the controller thread starts. 
private void ControllerThreadRunning()
{
    // And we're on our way.
    while ( !this.ServiceStopRequested )
    {
        // Start real work and then block until that finishes or crashes.
        var realWork = this.LaunchWorkAsync();
        realWork.Wait();
        // If SCM didn't request a service stop, the assumption is that 
        // the real work crashed and needs to be restarted.
        if ( !this.ServiceStopRequested )
        {
            this.PauseControllerThread("Pause before restarting work cycle.", this.RestartDelay);
        }
    }

    // This service will now stop.
    this.Cleanup();
}

这会异步启动服务的实际工作:

// This method handles all ceremony around the real work of this service.
private async Task LaunchWorkAsync()
{
    try 
    {
        // Setup progress reporting.
        var progressReport = new Progress<string>
                (progressInfo => { this.AppLog.Information(progressInfo, "ServiceMain.LaunchWorkAsync"); });
        var progress = progressReport as IProgress<string>;
        // Launch time.
        await Task.Factory.StartNew( () => this.DoWork(progress), TaskCreationOptions.LongRunning );
    }

    // Report any exception raised during the work cycle.
    catch (Exception ex)
    {
        this.AppLog.Error(string.Concat("Work cycle crashed", Environment.NewLine,
                                         ex.GetType().FullName, Environment.NewLine,
                                         ex.Message, Environment.NewLine,
                                         ex.StackTrace));
    }

    return;
}

这是服务的真正工作完成的地方:

// This is where this service's real work is done.
// The work cycles continuously until it's asked to stop.
// If the work crashes with an unhandled exception, the 
// controller thread will restart it after an appropriate delay.
private void DoWork(IProgress<string> progress)
{
    while (!this.ServiceStopRequested)
    {
        Thread.Sleep(5000);     // Simulated work cycle.
        progress.Report("Completed current cycle of work.");
    }
}

【讨论】:

  • 除了这个问题是重复的之外,请包含该链接中的相关内容或完全忽略它。
  • 我已经添加了相关代码。 OP 的问题使用 async/await 模式,我的回答也是如此。
猜你喜欢
  • 1970-01-01
  • 2017-01-23
  • 2011-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多