Back to "Verständnis der ASP.NET Core Request and Response Pipeline - Teil 2: Server und Hosting Layer"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

AI-Article ASP.NET ASP.NET Lifecycle

Verständnis der ASP.NET Core Request and Response Pipeline - Teil 2: Server und Hosting Layer

Sunday, 09 November 2025

Einleitung

In Teil 1 haben wir die Gesamtarchitektur der ASP.NET Core Request and Response Pipeline erforscht. Jetzt tauchen wir tief in die Fundamentschicht ein: die Server- und Hosting-Infrastruktur. Hier beginnt alles – wo Ihre Anwendung zum Leben kommt und wo rohe Netzwerkanfragen in die strukturierte HttpContext Objekte, die durch Ihre Middleware-Pipeline fließen.

Das Verständnis dieser Ebene ist entscheidend, weil sie kontrolliert, wie Ihre Anwendung beginnt, wie sie konfiguriert ist und wie sie mit dem zugrunde liegenden Webserver interagiert. Ob Sie für die Produktion, die Optimierung der Leistung oder die Konfiguration von HTTPS bereitstellen, die Hosting-Ebene ist, wo diese Bedenken angesprochen werden.

HINWEIS: Dies ist Teil meiner Experimente mit KI / eine Möglichkeit, $1000 Calude Code Web Credits auszugeben. Ich habe dies eine BUNCH Papiere gefüttert, mein Verständnis, Fragen, die ich diesen Artikel generieren musste. Es macht Spaß und füllt eine Lücke, die ich nirgendwo sonst gefüllt gesehen habe.

Die zweilagige Architektur: Host und Server

ASP.NET Core trennt die Bedenken des Anwendungshostings und des Webdienstes in zwei unterschiedliche Ebenen:

  1. Der Gastgeber - Verwaltet die Lebensdauer der Anwendung, Konfiguration, Abhängigkeitsinjektion und Protokollierung
  2. Der Server - Behandelt HTTP-Kommunikation, lauscht Anfragen und verwaltet Verbindungen

Diese Trennung bietet Flexibilität: Sie können Server (Kestrel, HTTP.sys, IIS Integration) austauschen, ohne Ihren Anwendungscode zu ändern, oder Ihre Anwendung in verschiedenen Hosting-Umgebungen (Konsole-App, Windows-Service, systemd Daemon) ausführen, ohne die Serverkonfiguration zu ändern.

Die Hostebene

WebApplication und WebApplicationBuilder

In ASP.NET Core 6 und später wurde das Hosting-Modell mit WebApplication und WebApplicationBuilder. Dies ersetzte die älteren IHostBuilder und IWebHostBuilder Muster mit einer schlankeren API.

// Modern ASP.NET Core 8 application
var builder = WebApplication.CreateBuilder(args);

// Configure services during the build phase
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// Build the application
var app = builder.Build();

// Configure middleware after building
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

// Start the server and begin processing requests
app.Run();

Was passiert während der WebApplication.CreateBuilder()?

Wenn du anrufst WebApplication.CreateBuilder(args), ein erheblicher Teil der Initialisierung erfolgt:

// Simplified view of what CreateBuilder does internally
public static WebApplicationBuilder CreateBuilder(string[] args)
{
    var builder = new WebApplicationBuilder();

    // 1. Configure the host defaults
    //    - Content root path (Directory.GetCurrentDirectory())
    //    - Load appsettings.json and appsettings.{Environment}.json
    //    - Load environment variables
    //    - Load command-line arguments
    //    - Setup default logging providers (Console, Debug, EventSource, EventLog on Windows)

    // 2. Configure Kestrel as the default web server
    builder.WebHost.UseKestrel();

    // 3. Setup dependency injection container
    //    - Creates the IServiceCollection
    //    - Registers core services

    // 4. Configure the environment
    //    - Sets ASPNETCORE_ENVIRONMENT (Development, Staging, Production)
    //    - Determines if running in development mode

    // 5. Setup configuration system
    //    - Creates the IConfiguration hierarchy
    //    - Combines all configuration sources

    return builder;
}

Anpassen des Hosts

Sie haben umfassende Kontrolle darüber, wie der Host konfiguriert ist:

var builder = WebApplication.CreateBuilder(args);

// Configure Kestrel server options
builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024 * 1024; // 10 MB
    serverOptions.Limits.MinRequestBodyDataRate = new MinDataRate(
        bytesPerSecond: 100,
        gracePeriod: TimeSpan.FromSeconds(10)
    );
});

// Add additional configuration sources
builder.Configuration.AddJsonFile("customsettings.json", optional: true);
builder.Configuration.AddEnvironmentVariables(prefix: "MYAPP_");

// Configure logging
builder.Logging.ClearProviders(); // Remove defaults
builder.Logging.AddConsole();
builder.Logging.AddDebug();
builder.Logging.SetMinimumLevel(LogLevel.Warning);

// Change the content root and web root
builder.Environment.ContentRootPath = "/custom/path";
builder.Environment.WebRootPath = "/custom/wwwroot";

var app = builder.Build();

Der Service-Container

Der Abhängigkeits-Injektions-Container wird während der Host-Initialisierung aufgebaut. Hier registrierte Services stehen in Ihrer gesamten Anwendung zur Verfügung:

var builder = WebApplication.CreateBuilder(args);

// Singleton: One instance for the application lifetime
builder.Services.AddSingleton<IMyService, MyService>();

// Scoped: One instance per request
builder.Services.AddScoped<IRequestService, RequestService>();

// Transient: New instance every time it's requested
builder.Services.AddTransient<ITransientService, TransientService>();

// Configure options pattern
builder.Services.Configure<MyOptions>(
    builder.Configuration.GetSection("MyOptions")
);

// Access configuration directly during service registration
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<MyDbContext>(options =>
    options.UseSqlServer(connectionString)
);

var app = builder.Build();

Umgebung und Konfiguration

ASP.NET Core bietet ein ausgeklügeltes Konfigurationssystem, das mehrere Quellen zusammenführt:

var builder = WebApplication.CreateBuilder(args);

// Configuration is loaded in this order (later sources override earlier):
// 1. appsettings.json
// 2. appsettings.{Environment}.json
// 3. User secrets (in Development environment only)
// 4. Environment variables
// 5. Command-line arguments

// Access configuration
var mySetting = builder.Configuration["MySection:MySetting"];
var myValue = builder.Configuration.GetValue<int>("MySection:MyValue");

// Check environment
if (builder.Environment.IsDevelopment())
{
    // Development-specific configuration
    builder.Services.AddDatabaseDeveloperPageExceptionFilter();
}

if (builder.Environment.IsProduction())
{
    // Production-specific configuration
    builder.Configuration.AddAzureKeyVault(/* ... */);
}

var app = builder.Build();

Die Serverebene: Kestrel

Kestrel ist der plattformübergreifende Webserver von ASP.NET Core. Er ist schnell, leicht und in der Lage, Produktions-Workloads zu bewältigen. Das Verständnis der Fähigkeiten von Kestrel hilft Ihnen, die Leistung und Sicherheit Ihrer Anwendung zu optimieren.

Kestrel Architektur

flowchart TD
  cc[Client Connection]
  ch["Connection Handler Layer<br/>• TLS/SSL Termination (if HTTPS)<br/>• Protocol Negotiation (HTTP/1.1, HTTP/2, HTTP/3)"]
  parser["HTTP Protocol Parser<br/>• Request Line Parsing (Method, Path, Protocol)<br/>• Header Parsing<br/>• Body Reading"]
  ctx["HttpContext Creation<br/>• Creates HttpContext object<br/>• Populates Request properties<br/>• Prepares Response object"]
  pipeline[Middleware Pipeline]

  cc --> ch --> parser --> ctx --> pipeline

Kestrel Architecture - Tiefere Tauchgänge

Um zu verstehen, wie Bytes zu einem HttpContext werden, den Ihre Middleware verwenden kann, hilft es, auf Kestrel-internen Fluss und Verantwortlichkeiten zu vergrößern.

flowchart LR
  subgraph os[OS / Network Stack]
    net[(TCP/UDP Sockets)]
  end

  subgraph kestrel[Kestrel Server]
    accept["Connection Accept Loop<br/>(.NET Sockets)"]

    subgraph connmw[Per-Connection Middleware]
      tls["TLS Termination / ALPN<br/>(Selects HTTP/1.1 vs HTTP/2 vs HTTP/3)"]
      limits["Connection & Request Limits<br/>(timeouts, sizes, rate limits)"]
      logging[Connection Logging]
    end

    subgraph proto[Protocol Handlers]
      h1["HTTP/1.1 Handler<br/>(keep-alive, chunked, pipelining)"]
      h2["HTTP/2 Handler<br/>(multiplexing, HPACK)"]
      h3["HTTP/3 Handler<br/>(QUIC, QPACK)"]
    end

    subgraph io[High-Perf IO]
      pipes["System.IO.Pipelines<br/>(zero-copy buffers)"]
      parser2[HTTP Parser]
    end

    features["Feature Mapping<br/>(IFeatureCollection)"]
    ctxpool[HttpContext Pool]
    appinvoke[IHttpApplication.ProcessRequestAsync]
  end

  app[Your Middleware Pipeline]

  net --> accept --> connmw --> proto
  proto --> io --> features --> ctxpool --> appinvoke --> app
sequenceDiagram
  autonumber
  participant C as Client
  participant S as Socket
  participant K as Kestrel
  participant P as Protocol Handler
  participant A as App (Middleware)

  C->>S: Connect (TCP/QUIC)
  S->>K: New connection accepted
  K->>K: TLS handshake + ALPN
  K->>P: Select protocol (HTTP/1.1, 2, or 3)
  loop Read/Parse
    P->>P: Read using System.IO.Pipelines
    P->>P: Parse request line/headers/body
  end
  P->>K: Build features + rent HttpContext from pool
  K->>A: ProcessRequestAsync(HttpContext)
  A-->>K: Writes response via Pipes
  K-->>C: Flush/Send response frames
  Note over K,C: Backpressure applied when client is slow

Wichtige Internale zu wissen:

  • TLS- und ALPN-Auswahl entscheiden, welcher Protokoll-Handler für diese Verbindung läuft.
  • System.IO.Pipelines untermauert alle Parsen und Schreiben für minimale Allokationen und hohen Durchsatz.
  • Feature Mapping (IFeatureCollection) stellt Serverfunktionen auf niedriger Ebene in HttpContext frei, ohne sie an Kestrel-Typen zu binden.
  • HttpContext-Objekte werden gepoolt, um den GC-Druck zu reduzieren; sie werden zurückgesetzt und pro Anfrage wiederverwendet.
  • Der Gegendruck wird durch Pipes angewendet, wenn der Client nicht schnell genug lesen kann; der Server wont over-buffer schreibt.
  • Timeouts und Limits (keep-alive, Header, Request Body Size, HTTP/2 Stream Limits) schützen den Server vor Slowloris und Ressourcenerschöpfung.
  • Threading: Die meisten Arbeiten laufen auf dem ThreadPool; Protokollhandler vermeiden pro-Anfrage Thread-Erstellung und bevorzugen async-Fortsetzungen.

Kestrel-Endpunkte konfigurieren

Sie können konfigurieren, welche Endpunkte Kestrel anhört und wie:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(options =>
{
    // Listen on all network interfaces on port 5000 (HTTP)
    options.Listen(IPAddress.Any, 5000);

    // Listen on localhost port 5001 (HTTPS)
    options.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("certificate.pfx", "password");
    });

    // Listen on specific IP with HTTP/2
    options.Listen(IPAddress.Parse("192.168.1.100"), 5002, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http2;
    });

    // Unix domain socket (Linux/macOS)
    options.ListenUnixSocket("/tmp/myapp.sock");

    // Named pipe (Windows)
    options.ListenNamedPipe("mypipename");
});

var app = builder.Build();

Alternativ können Sie Endpunkte über appsettings.json konfigurieren:

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "Https": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "certificate.pfx",
          "Password": "your-password"
        }
      }
    }
  }
}
var builder = WebApplication.CreateBuilder(args);

// Endpoints are automatically configured from appsettings.json
// when you don't explicitly call ConfigureKestrel

var app = builder.Build();

HTTPS-Konfiguration

HTTPS ist für Produktionsanwendungen unerlässlich. Kestrel bietet verschiedene Möglichkeiten, TLS zu konfigurieren:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(options =>
{
    options.Listen(IPAddress.Any, 5001, listenOptions =>
    {
        // Option 1: Certificate from file
        listenOptions.UseHttps("certificate.pfx", "password");

        // Option 2: Certificate from store (Windows)
        listenOptions.UseHttps(storeCert =>
        {
            storeCert.Subject = "localhost";
            storeCert.Store = "My";
            storeCert.Location = StoreLocation.CurrentUser;
            storeCert.AllowInvalid = false; // Don't allow invalid certs
        });

        // Option 3: Development certificate
        listenOptions.UseHttps(); // Uses development certificate in Development environment

        // Option 4: Configure TLS details
        listenOptions.UseHttps(httpsOptions =>
        {
            httpsOptions.ServerCertificate = LoadCertificate();
            httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
            httpsOptions.CheckCertificateRevocation = true;
            httpsOptions.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13;

            // Client certificate validation
            httpsOptions.ClientCertificateValidation = (certificate, chain, errors) =>
            {
                // Custom validation logic
                return errors == SslPolicyErrors.None;
            };
        });
    });
});

var app = builder.Build();

Kestrel Limits und Performance Tuning

Kestrel bietet zahlreiche Optionen, um die Ressourcennutzung zu steuern und die Leistung zu optimieren:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(options =>
{
    // Connection limits
    options.Limits.MaxConcurrentConnections = 100;
    options.Limits.MaxConcurrentUpgradedConnections = 100;

    // Request limits
    options.Limits.MaxRequestBodySize = 10 * 1024 * 1024; // 10 MB
    options.Limits.MaxRequestHeaderCount = 100;
    options.Limits.MaxRequestHeadersTotalSize = 32 * 1024; // 32 KB
    options.Limits.MaxRequestLineSize = 8 * 1024; // 8 KB

    // Keep-alive timeout
    options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);

    // Request header read timeout
    options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(30);

    // Minimum data rate for request body
    options.Limits.MinRequestBodyDataRate = new MinDataRate(
        bytesPerSecond: 240,
        gracePeriod: TimeSpan.FromSeconds(5)
    );

    // Minimum data rate for response body
    options.Limits.MinResponseDataRate = new MinDataRate(
        bytesPerSecond: 240,
        gracePeriod: TimeSpan.FromSeconds(5)
    );

    // HTTP/2 specific limits
    options.Limits.Http2.MaxStreamsPerConnection = 100;
    options.Limits.Http2.HeaderTableSize = 4096;
    options.Limits.Http2.MaxFrameSize = 16 * 1024; // 16 KB
    options.Limits.Http2.MaxRequestHeaderFieldSize = 8 * 1024; // 8 KB
    options.Limits.Http2.InitialConnectionWindowSize = 128 * 1024; // 128 KB
    options.Limits.Http2.InitialStreamWindowSize = 96 * 1024; // 96 KB
});

var app = builder.Build();

HTTP/2 und HTTP/3 Unterstützung

Kestrel unterstützt moderne HTTP-Protokolle:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(options =>
{
    // HTTP/1.1 only
    options.Listen(IPAddress.Any, 5000, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http1;
    });

    // HTTP/1.1 and HTTP/2
    options.Listen(IPAddress.Any, 5001, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
        listenOptions.UseHttps();
    });

    // HTTP/2 only
    options.Listen(IPAddress.Any, 5002, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http2;
        listenOptions.UseHttps();
    });

    // HTTP/3 (QUIC) - requires .NET 7+
    options.Listen(IPAddress.Any, 5003, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
        listenOptions.UseHttps();
    });
});

var app = builder.Build();

Server-Features

Kestrel stellt Server-Fähigkeiten durch die IFeatureCollection verfügbar am HttpContext:

app.Use(async (context, next) =>
{
    // Check if HTTP/2 is being used
    var http2Feature = context.Features.Get<IHttpRequestFeature>();
    if (http2Feature?.Protocol == "HTTP/2")
    {
        Console.WriteLine("Using HTTP/2");
    }

    // Access connection features
    var connectionFeature = context.Features.Get<IHttpConnectionFeature>();
    Console.WriteLine($"Remote IP: {connectionFeature?.RemoteIpAddress}");
    Console.WriteLine($"Local IP: {connectionFeature?.LocalIpAddress}");

    // TLS information
    var tlsFeature = context.Features.Get<ITlsConnectionFeature>();
    if (tlsFeature?.ClientCertificate != null)
    {
        Console.WriteLine($"Client cert: {tlsFeature.ClientCertificate.Subject}");
    }

    // Request body pipe for high-performance scenarios
    var bodyPipeFeature = context.Features.Get<IRequestBodyPipeFeature>();
    if (bodyPipeFeature != null)
    {
        var reader = bodyPipeFeature.Reader;
        // Use System.IO.Pipelines for zero-copy reads
    }

    await next(context);
});

Anwendung Lebenslange Ereignisse

Der Host bietet Hooks für Anwendungslebenszyklus-Events:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Get the application lifetime
var lifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();

// Application started event
lifetime.ApplicationStarted.Register(() =>
{
    Console.WriteLine("Application has started");
    // Perform startup tasks (warm up caches, etc.)
});

// Application stopping event
lifetime.ApplicationStopping.Register(() =>
{
    Console.WriteLine("Application is stopping");
    // Begin graceful shutdown (stop accepting new requests)
});

// Application stopped event
lifetime.ApplicationStopped.Register(() =>
{
    Console.WriteLine("Application has stopped");
    // Cleanup resources
});

app.Run();

Sie können auch implementieren IHostedService für Hintergrundaufgaben:

public class MyBackgroundService : IHostedService, IDisposable
{
    private Timer? _timer;
    private readonly ILogger<MyBackgroundService> _logger;

    public MyBackgroundService(ILogger<MyBackgroundService> logger)
    {
        _logger = logger;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Background service is starting");

        _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromMinutes(5));

        return Task.CompletedTask;
    }

    private void DoWork(object? state)
    {
        _logger.LogInformation("Background service is working");
        // Perform periodic work
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Background service is stopping");

        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}

// Register the service
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHostedService<MyBackgroundService>();
var app = builder.Build();

Anmutiger Shutdown

ASP.NET Core behandelt anmutiges Herunterfahren automatisch, aber Sie können das Verhalten anpassen:

var builder = WebApplication.CreateBuilder(args);

// Configure shutdown timeout
builder.WebHost.ConfigureKestrel(options =>
{
    options.AddServerHeader = false; // Remove Server header for security
});

builder.Host.ConfigureHostOptions(options =>
{
    // How long to wait for the application to shut down gracefully
    options.ShutdownTimeout = TimeSpan.FromSeconds(30);
});

var app = builder.Build();

// During shutdown, Kestrel:
// 1. Stops accepting new connections
// 2. Waits for existing requests to complete (up to ShutdownTimeout)
// 3. Aborts remaining requests
// 4. Disposes services
// 5. Runs ApplicationStopped callbacks

app.Run();

Produktions-Hosting-Szenarien

Hinter einem Reverse Proxy laufen

In der Produktion steht Kestrel typischerweise hinter einem Reverse Proxy (nginx, Apache, IIS):

var builder = WebApplication.CreateBuilder(args);

// Configure forwarded headers for reverse proxy scenarios
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;

    // If your proxy is on a known network
    options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("10.0.0.0"), 8));
    options.KnownProxies.Add(IPAddress.Parse("10.0.0.1"));

    // Required when running in containers/Kubernetes
    options.ForwardedHeaders = ForwardedHeaders.All;
    options.KnownNetworks.Clear();
    options.KnownProxies.Clear();
});

var app = builder.Build();

// Must be before other middleware
app.UseForwardedHeaders();

app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

Windows-Service-Hosting

var builder = WebApplication.CreateBuilder(args);

// Enable Windows Service lifetime
builder.Host.UseWindowsService();

// Configure content root for Windows Service
builder.Host.UseContentRoot(AppContext.BaseDirectory);

var app = builder.Build();

app.Run();

Linux Systemd Service Hosting

var builder = WebApplication.CreateBuilder(args);

// Enable systemd lifetime
builder.Host.UseSystemd();

var app = builder.Build();

app.Run();

Erweitert: Benutzerdefinierter Server

Während Kestrel die Standardwahl ist, können Sie bei Bedarf einen benutzerdefinierten Server implementieren:

public class CustomServer : IServer
{
    private IFeatureCollection _features = new FeatureCollection();

    public IFeatureCollection Features => _features;

    public Task StartAsync<TContext>(IHttpApplication<TContext> application,
        CancellationToken cancellationToken) where TContext : notnull
    {
        // Start listening for connections
        // Create HttpContext for each request
        // Invoke application.ProcessRequestAsync(httpContext)
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        // Stop accepting new connections
        // Wait for existing requests to complete
        return Task.CompletedTask;
    }

    public void Dispose()
    {
        // Cleanup resources
    }
}

// Use custom server
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseServer(new CustomServer());
var app = builder.Build();

Schlüssel zum Mitnehmen

  • Der Host verwaltet Anwendungslebensdauer, Konfiguration, DI und Protokollierung
  • Kestrel ist ein leistungsstarker, plattformübergreifender Webserver
  • Sie können Endpunkte, HTTPS, Protokolle und Leistungsgrenzen konfigurieren
  • Der Server erzeugt HttpContext Objekte, die durch die Middleware-Pipeline fließen
  • Anmutige Herunterfahren sorgt dafür, dass Anfragen vor Beendigung der Anwendung abgeschlossen werden
  • Produktionsbereitstellungen verwenden typischerweise Kestrel hinter einem umgekehrten Proxy
  • Das IFeatureCollection bietet Zugriff auf Low-Level-Server-Funktionen

Das Verständnis der Server- und Hostingebene gibt Ihnen die Kontrolle darüber, wie Ihre Anwendung startet, wie sie Verbindungen verarbeitet und wie sie unter Last ausgeführt wird. Diese Grundlage unterstützt alles, was in den Ebenen oben passiert.


logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.