簡體   English   中英

當Kestrel收到請求時,無法停止asp.net核心Windows服務

[英]Unable to stop asp.net core Windows Service when Kestrel receives requests

我們使用在.net 4.5.1上運行的asp.net核心作為Windows服務。 Kestrel用作Web服務器(Kestrel版本為1.1.2)。 它是根據Windows服務中的Host a ASP.NET Core應用程序配置的。 我們還使用在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處理之前停止Krestel或阻止OnStopping事件中的新傳入連接。

堆棧跟蹤:

Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException:錯誤-4082 EBUSY資源繁忙或已鎖定
在System.Runtime.InteropServices.SafeHandle.InternalDispose()中的Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvLoopHandle.ReleaseHandle()中的Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.Libuv.loop_close(UvLoopHandle句柄)中在System.Runtime.InteropServices.SafeHandle.Dispose中(布爾處理)
在Microsoft.AspNetCore.Server.Kestrel.Internal.KestrelThread.ThreadStart(Object parameter)中的System.Runtime.InteropServices.SafeHandle.Dispose()中

在Microsoft.AspNetCore.Server.Kestrel.Internal中的System.Threading.Tasks.Task.WaitAll(Task []任務,Int32 millisecondsTimeout,CancellationToken cancellationToken)中的Microsoft.AspNetCore.Server.Kestrel.Internal.KestrelThread.d__51.MoveNext()中.KestrelEngine.Dispose()
在Microsoft.Extensions.DependencyInjection.ServiceProvider.Dispose()中的Microsoft.AspNetCore.Server.Kestrel.KestrelServer.Dispose()中
在Microsoft.AspNetCore.Hosting.Internal.WebHost.Dispose()中

Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException:錯誤-4082 EBUSY資源忙或已鎖定在Microsoft.AspNetCore.Server.Kestrel中的Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.Libuv.loop_close(UvLoopHandle句柄)中System.Runtime.InteropServices.SafeHandle.Dispose中的System.Runtime.InteropServices.SafeHandle.InternalDispose()中的.Internal.Networking.UvLoopHandle.ReleaseHandle()(布爾處理)
在Microsoft.AspNetCore.Server.Kestrel.Internal.KestrelThread.ThreadStart(Object parameter)中的System.Runtime.InteropServices.SafeHandle.Dispose()中

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

從KestrelServer.Dispose()拋出的EBUSY異常在Kestrel的2.0版本中得到修復 我認為你的服務掛起的原因是因為_host?.Dispose()正在拋出,這會阻止OnStopped(); OnStop()方法中調用。

在此期間,吞下異常以確保OnStopped(); 總是被調用應該允許服務停止。 如果要重新啟動服務器,請確保構建新的WebHost。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM