Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 按下“取消”键(CTRL+;C)强制停止服务时,控制台中的Topshelf_C#_.net_Topshelf - Fatal编程技术网

C# 按下“取消”键(CTRL+;C)强制停止服务时,控制台中的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

我希望Topshelf在控制台中调试时停止我的服务

我的代码:

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中,您需要:

  • 转到项目属性,然后导航到调试窗格,选中 “启用非托管代码调试”
  • 工具栏调试->异常-> 然后取消C++异常和Win32异常。< /LI>
    在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异常处理程序,如本问题所述: