Can't stop asp.net underlying Windows service when Kestrel receives requests

We are using asp.net core running on .net 4.5.1 as windows service. Kestrel is used as a web server (Kestrel version is 1.1.2). It has been configured as per Accept ASP.NET Core Application on Windows Service . We also use SignalR running on OWIN.

The problem occurs when two events occur simultaneously: the Windows service stops and some new web requests were received by Krestel. If these conditions are met, the Windows service stops responding and hangs.

Windows was unable to stop the Topshelf.Host service on the local computer. Error 1061: The service cannot receive control messages at this time.

Lock code:

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)
    {
    }

//...
}

      

Further investigation revealed that an unhandled exception was thrown when disposing of _host in WebHostService.cs .

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

      

As described below, it throws an exception "Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -4082 EBUSY resource busy or blocked"

Question:

Is there a way to avoid this error and prevent Windows Service from freezing? For example. stop using Krestel before vhost deletes or prevents new incoming connection in OnStopping event.

Stacktrace:

Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -4082 EBUSY resource busy or locked
at Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.Libuv.loop_close (UvLoopHandle handle) at Microsoft.AspKNetCore.Server .Internal.Networking.UvLoopHandle.ReleaseHandle () at System.Runtime.InteropServices.SafeHandle.InternalDispose () at System.Runtime.InteropServices.SafeHandle.Dispose (Boolean disposing)
at System.Runtime.InteropServices.Safe .AspNetCore.Server.Kestrel.Internal.KestrelThread.ThreadStart (Object parameter)

at Microsoft.AspNetCore.Server.Kestrel.Internal.KestrelThread.d__51.MoveNext () at System.Threading.Tasks.Task.WaitAll (Task [] Tasks, Int32 millisecondsTimeout, CancellationToken cancelationToken) at Microsoft.AspNetCore.Inerver.Kestrel .KestrelEngine.Dispose ()
to Microsoft.AspNetCore.Server.Kestrel.KestrelServer.Dispose () to Microsoft.Extensions.DependencyInjection.ServiceProvider.Dispose ()
to Microsoft.AspNetCore.Hosting.Internal.WebHost.Dispose ()

Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -4082 EBUSY resource busy or blocked Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.Libuv.loop_close (UvLoopHandle handle) in Microsoft.AspNetCore.Server.Kestrel Internal.Networking.UvLoopHandle.ReleaseHandle () at System.Runtime.InteropServices.SafeHandle.InternalDispose () at System.Runtime.InteropServices.SafeHandle.Dispose (Boolean disposing)
at System.Runtime.InteropServices.SafeHandle AspNetCore.Server.Kestrel.Internal.KestrelThread.ThreadStart (Object parameter)

at Microsoft.AspNetCore.Server.Kestrel.Internal.KestrelThread.d__51.MoveNext ()

+3


source to share


1 answer


EBUSY exceptions thrown from KestrelServer.Dispose () will be fixed in version 2.0 of Kestrel. I think the reason your service is hanging is because it _host?.Dispose()

throws, which prevents it from being called OnStopped();

inside the method OnStop()

.



In the meantime, swallowing the exception to ensure that OnStopped();

always gets thrown should allow the service to stop. Make sure to create a new WebHost if you want to restart the server.

0


source







All Articles