C# Kestrel收到请求时无法停止asp.net核心Windows服务

C# Kestrel收到请求时无法停止asp.net核心Windows服务,c#,service,asp.net-core,kestrel-http-server,C#,Service,Asp.net Core,Kestrel Http Server,我们使用运行在.net 4.5.1上的asp.net内核作为Windows服务。Kestrel用作web服务器(Kestrel版本为1.1.2)。 它是按照配置的。我们还使用在OWIN上运行的信号器 当两个事件同时发生时就会出现问题:Windows服务正在停止,Krestel收到了一些新的web请求。如果满足这些条件,Windows服务将停止响应并挂起 Windows无法停止本地计算机上的Topshelf.Host服务。 错误1061:服务此时无法接受控制消息 混淆代码: 如下所述,它引发异常“

我们使用运行在.net 4.5.1上的asp.net内核作为Windows服务。Kestrel用作web服务器(Kestrel版本为1.1.2)。 它是按照配置的。我们还使用在OWIN上运行的信号器

当两个事件同时发生时就会出现问题:Windows服务正在停止,Krestel收到了一些新的web请求。如果满足这些条件,Windows服务将停止响应并挂起

Windows无法停止本地计算机上的Topshelf.Host服务。 错误1061:服务此时无法接受控制消息

混淆代码:

如下所述,它引发异常“Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException:错误-4082 EBUSY资源忙或已锁定”

问题是: 有没有办法避免此类错误并防止Windows服务挂起?例如,在主机处理之前停止Krestel,或在OnStopping事件中阻止新的传入连接

堆栈跟踪:

Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: 错误-4082 EBUSY资源忙或已锁定
在Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.Libuv.loop\u close(UvLoopHandle)中 处理) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvLoopHandle.ReleaseHandle() 在中的System.Runtime.InteropServices.SafeHandle.InternalDispose()中 System.Runtime.InteropServices.SafeHandle.Dispose(布尔处置)
在中的System.Runtime.InteropServices.SafeHandle.Dispose()中 Microsoft.AspNetCore.Server.Kestrel.Internal.KestrelThread.ThreadStart(对象 参数)

在 Microsoft.AspNetCore.Server.Kestrel.Internal.KestrelThread.d_u51.MoveNext() 在System.Threading.Tasks.Task.WaitAll(Task[]Tasks,Int32)中 毫秒计时,取消令牌(取消令牌) Microsoft.AspNetCore.Server.Kestrel.Internal.KestrelEngine.Dispose()
在Microsoft.AspNetCore.Server.Kestrel.KestrelServer.Dispose()中 Microsoft.Extensions.DependencyInjection.ServiceProvider.Dispose()
在Microsoft.AspNetCore.Hosting.Internal.WebHost.Dispose()中

Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: 错误-4082 EBUSY资源正忙或已锁定 Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.Libuv.loop\u close(UvLoopHandle 处理) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvLoopHandle.ReleaseHandle() 在中的System.Runtime.InteropServices.SafeHandle.InternalDispose()中 System.Runtime.InteropServices.SafeHandle.Dispose(布尔处置)
在中的System.Runtime.InteropServices.SafeHandle.Dispose()中 Microsoft.AspNetCore.Server.Kestrel.Internal.KestrelThread.ThreadStart(对象 参数)

Microsoft.AspNetCore.Server.Kestrel.Internal.KestrelThread.d_u51.MoveNext()


Kestrel 2.0版本中KestrelServer.Dispose()引发的EBUSY异常。我认为您的服务挂起的原因是因为
\u host?.Dispose()
正在抛出阻止
停止()OnStop()方法中调用code>


同时,吞咽异常以确保
OnStopped()总是被调用应该允许停止服务。如果要重新启动服务器,请确保构建新的网络主机。

看起来Kestrel有问题。试图提出一个问题
var port = Global.Settings.Port;
var hostBuilder = new WebHostBuilder()                  
                .UseKestrel()                   
                .UseStartup<Startup>()
                .UseUrls("http://+:" + port);

if (runAsService)
 {                    
       hostBuilder.UseContentRoot(directoryPath);
       Directory.SetCurrentDirectory(directoryPath);
 }
 else
 {                    
     hostBuilder.UseContentRoot(Directory.GetCurrentDirectory());
 }

var host = hostBuilder.Build();
if (runAsService)
{                 
    host.RunAsCustomService();
}
else
{                    
      host.Run();
}

public static class WebHostServiceExtensions
{
    public static void RunAsCustomService(this IWebHost host)
    {
        var webHostService = new CustomWebHostService(host);
        ServiceBase.Run(webHostService);
    }
}
internal class CustomWebHostService : WebHostService
{
    public CustomWebHostService(IWebHost host) : base(host)
    {
    }

//...
}
protected sealed override void OnStop()
{
    _stopRequestedByWindows = true;
    OnStopping();
    _host?.Dispose();
    OnStopped();
}