C# 按下“取消”键(CTRL+;C)强制停止服务时,控制台中的Topshelf
我希望Topshelf在控制台中调试时停止我的服务 我的代码:C# 按下“取消”键(CTRL+;C)强制停止服务时,控制台中的Topshelf,c#,.net,topshelf,C#,.net,Topshelf,我希望Topshelf在控制台中调试时停止我的服务 我的代码: public class Program { private static ILog _log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); public static void Main(string[] args) { HostFactory.Run(Confi
public class Program
{
private static ILog _log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public static void Main(string[] args)
{
HostFactory.Run(Configure);
}
/// <summary>
/// Configures the service host.
/// </summary>
/// <param name="cfg">The HostConfigurator</param>
private static void Configure(HostConfigurator cfg)
{
try
{
cfg.Service<ServiceHost>(s =>
{
s.ConstructUsing(name => new ServiceHost());
s.WhenStarted(host => host.StartService());
s.WhenStopped(host => host.StopService());
});
cfg.RunAsLocalSystem();
cfg.StartManually();
cfg.SetDisplayName(DisplayName);
cfg.SetServiceName(ServiceName);
cfg.UseLog4Net();
}
catch (Exception ex)
{
_log.Fatal("Exception on Startup", ex);
throw;
}
}
}
公共类程序
{
私有静态ILog_log=LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
公共静态void Main(字符串[]args)
{
HostFactory.Run(配置);
}
///
///配置服务主机。
///
///主机配置程序
专用静态无效配置(HostConfigurator cfg)
{
尝试
{
cfg.Service(s=>
{
s、 ConstructUsing(name=>newServiceHost());
s、 启动时(host=>host.StartService());
s、 停止时(host=>host.StopService());
});
cfg.RunAsLocalSystem();
cfg.每年开始();
SetDisplayName(DisplayName);
cfg.SetServiceName(ServiceName);
cfg.UseLog4Net();
}
捕获(例外情况除外)
{
_log.Fatal(“启动时异常”,例如);
投掷;
}
}
}
但当我按CTRL+C时,它挂起在Microsoft.VisualStudio.HostingProcess.HostProc.WaitForThreadExit中
当我按下CTRL+C时,我希望立即调用host=>host.StopService()
这可能吗?应该可以通过向
控制台添加事件处理程序来拦截CTRL+C。CancelKeyPress
事件:
Console.CancelKeyPress += (s, e) => host.StopService();
最可能的罪魁祸首是您的服务的
StartService
方法没有将控制权返回到Topshelf。您的StartService
是做什么的?它应该只初始化任何资源并启动事件循环/线程。您能否运行服务安装启动
并启动它?如果服务在启动时超时,这也会强化您的启动不会返回的想法 这是.NET4.0的一个已知错误,有一个解决方法,但它很糟糕
在VS2010中,您需要:
在ServiceHost类中,实现IDisposeable,添加Dispose方法,并处理所有线程对象。我已经尝试过,它总是在“Microsoft.VisualStudio.HostingProcess.HostProc.WaitForThreadExit”上阻塞。这似乎是.net framework中的一个错误:@leozilla是的,但它似乎只有在调试时才会出现。也许您可以在调试时使用不同的组合键来停止服务?例如,我正在等待“q”键按下,然后完全关闭。Topshelf的ConsoleRunHost已经可以处理Ctrl+C键按下。您是否尝试过关闭项目属性中的VS主机?好主意!我尝试过,但现在它挂在>mscorlib.dll!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle WaitableSaffeHandle,长毫秒刺激,bool hasThreadAffinity,bool exitContext)+0x2b字节:(Ctrl+C是一个相当大的锤子,代码很难避开它。您需要发布一个更好的堆栈跟踪来给我们一个猜测。注意.NET 4.5 RTM控制台类中的常见死锁,请确保启用Windows Update以获得修复它的服务版本。解决方案是启用非托管调试并关闭Control+C异常处理程序,如本问题所述: