在 ASP.Net Core 2.0 中由于任何原因停止 Kestrel 时的预制清理

Dar*_*gel 2 c# asp.net-core-mvc asp.net-core asp.net-core-2.0

我正在开发一个 Web 应用程序,该应用程序运行多个线程,这些线程处理套接字和文件 I/O。所以在应用程序关闭的情况下,我首先要完成这些线程并清理它们。

我已经找到了以下代码,它在正常关机的情况下效果很好。

public class Startup 
{
    public void Configure(IApplicationBuilder app, IApplicationLifetime applicationLifetime) 
    {
        applicationLifetime.ApplicationStopping.Register(OnShutdown);
    }

    private void OnShutdown()
    {
         // Do your cleanup here
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,当您进行非正常关机时,不会调用 OnShutDown() 方法。

在 Forms 中,您可以使用以下代码检测各种关闭原因:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)  
{  
    switch (e.CloseReason)  
    {  
        case CloseReason.ApplicationExitCall:  
            // The Exit method of the Application class was called.  
            break;  
        case CloseReason.FormOwnerClosing:  
            // The owner form is closing.  
            break;  
        case CloseReason.MdiFormClosing:  
            // The parent form is closing.  
            break;  
        case CloseReason.None:  
            // Unknown closing reason.  
            break;  
        case CloseReason.TaskManagerClosing:  
            // The application is being closed from the TaskManager.  
            break;  
        case CloseReason.UserClosing:  
            // The user is closing the form through the UI.  
            break;  
        case CloseReason.WindowsShutDown:  
            // Windows is closing the application because it is shutting down.  
            break;  
    }  
} 
Run Code Online (Sandbox Code Playgroud)

在 ASP.Net Core 2.0 中是否有类似的东西可以在仅正常关闭的 stat 中检测任何类型的关闭?

Chr*_*att 5

事件处理取决于成功退出。如果您执行诸如硬重启或应用程序崩溃之类的操作,则没有机会处理任何事情,因为它已经消失了。这就是重点:它被迫退出,所以它不能做任何事情。

也就是说,这里的问题实际上不是问题,也不是设计问题。首先,如果进程退出,线程会随之而去。没有什么可“清理”的。套接字句柄等只是内存中的指针,它们也与进程一起使用。

如果进程挂起,那就是另一回事了。在这种情况下,它可以保留资源,因为它在技术上仍在运行。然而,真正的问题是修复导致进程挂起的任何东西,而不是弄清楚如何在它发生时释放资源。

请记住,Web 服务器旨在快速响应传入的请求。这应该是一个几乎瞬间的过程。它的设计目的不是为了处理一段时间的请求,而是做一堆工作。如果您需要执行诸如连接到套接字之类的操作,那么很可能会将其卸载到外部进程中,例如控制台应用程序、Windows 服务等。然后,您的 Web 应用程序可以简单地将工作交给它并继续。您可以提供一个端点来检查状态、进度等,并通过 SignalR 或 AJAX 长轮询使用它来更新客户端有关工作的进度/在完成时通知他们。