我们正在使用.net 4.5.1上运行的asp.net核心作为Windows服务。 Kestrel用作Web服务器(Kestrel版本为1.1.2)。 它是根据Host an ASP.NET Core app in a Windows Service配置的。我们还使用在OWIN上运行的SignalR。
当两个事件同时发生时出现问题:Windows服务正在停止,Krestel收到了一些新的Web请求。如果满足这些条件,则Windows服务停止响应并挂起。
Windows无法停止本地计算机上的Topshelf.Host服务。 错误1061:此时服务无法接受控制消息。
配置代码:
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)
{
}
//...
}
进一步调查显示在WebHostService.cs中部署_host时发生未处理的异常。
protected sealed override void OnStop()
{
_stopRequestedByWindows = true;
OnStopping();
_host?.Dispose();
OnStopped();
}
如下所述,它引发了一个异常“Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException:错误-4082 EBUSY资源忙或已锁定”
有没有办法避免此类错误并阻止Windows服务挂起?例如。在_host处置或阻止OnStopping事件中的新传入连接之前停止Krestel。
Stacktrace:
Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: 错误 -4082 EBUSY资源繁忙或已锁定
在Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.Libuv.loop_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__51.MoveNext() 在System.Threading.Tasks.Task.WaitAll(Task []任务,Int32 millisecondsTimeout,CancellationToken cancellationToken)in 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_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__51.MoveNext()
答案 0 :(得分:0)
在Kestrel 2.0版本中从KestrelServer.Dispose()will be fixed抛出的EBUSY异常。我认为您的服务挂起的原因是因为_host?.Dispose()
正在抛出,导致OnStopped();
方法无法调用OnStop()
。
与此同时,吞下异常以确保始终调用OnStopped();
应允许停止服务。如果要重新启动服务器,请确保构建新的WebHost。