Windows 已安装服务。但是开始,停止按钮被禁用
Windows Service installed. But start, stop buttons disabled
我创建了 windows 服务。安装 Installutil.exe 成功,但是当我按下开始按钮时出现进度条 "starting",然后它停在 50%。我必须取消。取消服务后完美运行,但启动、停止和暂停命令被禁用。如果我想停止服务,我必须卸载服务。可能是什么原因?
主要方法:
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new TelegramBotService()
};
ServiceBase.Run(ServicesToRun);
}
这是我的服务class:
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");
}
}
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.");
}
}
我创建了 windows 服务。安装 Installutil.exe 成功,但是当我按下开始按钮时出现进度条 "starting",然后它停在 50%。我必须取消。取消服务后完美运行,但启动、停止和暂停命令被禁用。如果我想停止服务,我必须卸载服务。可能是什么原因?
主要方法:
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new TelegramBotService()
};
ServiceBase.Run(ServicesToRun);
}
这是我的服务class:
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");
}
}
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.");
}
}