在生产中实例化ASP.NET Core应用程序

时间:2018-02-28 15:39:12

标签: c# asp.net-core

ASP.NET Core从位于Main Program class文件内的Program.cs方法开始执行。这构建了一个Web托管环境,并告诉Web主机开始运行。然后,有startup.cs个文件。

在开发.NET Core Web应用程序时,我必须在本地构建它(例如,通过Ctrl-F5)。执行此操作时,Main方法正在运行。每次下次我想打开我的网络应用程序时,鉴于IIS Express已经启动,我只是在写http://localhost:65040。通过这样做,Main方法没有再次运行,但一切正常(路由等...)。所以, 我有以下问题

.NET Core如何知道在收到上述Http请求(http://localhost:65040)后该怎么做?例如,它是如何实现路由的

app.UseMvc(routes =>
{
    app.UseMvcWithDefaultRoute();
})
Startup.cs中的

没有再次投放? There is no need for that because IIS has already been informed?

如果上述想法是正确的,deployment到底发生了什么?然后我们的Http请求永远不会触发program.csstartup.cs那么,远程Web服务器以哪种方式被告知如何实现路由等?

3 个答案:

答案 0 :(得分:4)

无论托管您选择ASP.Net核心应用程序(IIS还是通过Kestrel进行自托管),方法Program.Main()Startup.ConfigureServices()Startup.Configure()在托管流程启动期间只执行一次。

当您使用Kestrel Web服务器启动exe文件时,很明显会执行Program.Main()。然而,在IIS中托管时是否实际调用它可能并不明显。实际上是这样的。当ASP.Net核心应用程序与IIS集成时,它通常由dotnet.exe运行程序执行(它也可以配置应用程序.exe文件的启动)。您可以在添加应用程序期间创建的web.config中进行检查:

<configuration>
  <system.webServer>
    <!-- ... -->
    <aspNetCore processPath="dotnet" arguments=".\TestMvcApplication.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
  </system.webServer>
</configuration>

因此它与使用命令dotnet.exe TestMvcApplication.dll运行应用程序时基本相同。在这种情况下会执行Program.Main(),后面会使用Startup方法。

如果没有基本构建Web主机的Main()方法,ASP.Net Core应用程序就无法运行。

当你触发后续查询时,它们由同一个托管应用程序处理(我的意思是这里的Windows进程相同)。 ASP.Net Core所需的所有配置(如路由,中间件,服务等)已经在此过程中连接。这就是ASP.Net Core能够处理请求的原因。

我希望这是你问题的答案。以下是一些有用的链接:

Hosting in ASP.NET Core

Host ASP.NET Core on Windows with IIS

Application startup in ASP.NET Core

答案 1 :(得分:3)

以下是从高级视图运行程序时会发生什么:

首先,与任何其他.NET应用程序一样,将调用Main方法,因为它是任何.NET应用程序的起点。

如果它是一个控制台应用程序,那么没什么特别的,只需运行代码并退出程序。

但对于Web应用程序,程序需要永远运行并侦听传入的HTTP请求。那么我们怎么能对我们的应用程序说这个呢?我们必须配置它。与任何其他框架一样,.NET Core有一些规则和约定,这是在.NET Core中构建Web应用程序的最简单方法:

public class Program
{
    public static void Main()
    {
        new WebHostBuilder()
            .UseKestrel()
            .Configure(app =>
            {
                app.Run(async context => await context.Response.WriteAsync("Hello World!"));
            })
            .Build()
            .Run();
    }
}

所以这里发生的是操作系统在进程中运行Main方法(使用处理线程)。我们创建一个WebHostBuilder并将其配置为使用Kestrel作为网络服务器并发回&#34; Hello World!&#34;字符串到任何传入的HTTP请求。 然后我们构建并运行WebHostBuilder

Configure方法的作用是创建一个管道,这样每个请求都将通过该管道的逻辑。您在Configure方法中看到的所有方法都只会为管道添加额外的逻辑,如身份验证,静态内容服务,配置路由等。

我应该注意,为了使用某些功能,我们必须先将它们添加到我们的程序中,这将在ConfigureServices()方法中完成,该方法在Configure()方法之前运行。

这里重要的方法是Run(),它阻塞调用线程(调用Main方法的线程)。所以Main方法永远不会完成,否则会退出程序。但我们的WebHost正在后台运行,并将响应HTTP请求。

总而言之,Main方法在应用程序启动期间只运行一次,并创建并配置WebHost以提供HTTP请求。无需为每个请求运行Main方法或创建新的WebHost

这些是一些基础知识,如果你想了解更多,你应该阅读Microsoft Docs。那里有许多有用的信息。

答案 2 :(得分:-1)

经过大量的学习和实验,我发现我的答案的关键点如下: Program.csStartup.cs仅在第一次正在运行 Http请求时才会运行。这是第一次配置Kestrel并通知它任何后续请求(例如路由)必须知道的一切。

老实说,我不知道应用程序如何区分第一个请求和其他请求,但我上面描述的内容肯定发生在开发和生产中。