Feldolgozói szolgáltatások a .NET-ben

A hosszú ideig futó szolgáltatások létrehozásának számos oka van, például:

  • Processzorigényes adatok feldolgozása.
  • Munkaelemek várólistára helyezése a háttérben.
  • Időalapú művelet végrehajtása ütemezés szerint.

A háttérszolgáltatás-feldolgozás általában nem jár felhasználói felülettel (UI), de a felhasználói felületek ezek köré építhetők. A .NET-keretrendszer korai napjaiban a Windows-fejlesztők létrehozhatják a Windows-szolgáltatásokat ezekhez a célokhoz. A .NET-tel most már használhatja a BackgroundServicesaját implementációját IHostedService, vagy implementálhatja a sajátját.

A .NET-ben már nem korlátozódik a Windowsra. Platformfüggetlen háttérszolgáltatásokat fejleszthet. Az üzemeltetett szolgáltatások naplózásra, konfigurálásra és függőséginjektálásra (DI) készek. Ezek a kódtárak bővítménycsomagjának részei, ami azt jelenti, hogy alapvető fontosságúak az általános gazdagéppel dolgozó .NET-számítási feladatokhoz.

Fontos

A .NET SDK telepítése a Microsoft.NET.Sdk.Worker feldolgozó sablont is telepíti. Más szóval a .NET SDK telepítése után létrehozhat egy új feldolgozót az új dotnet új feldolgozó parancsával. Ha Visual Studiót használ, a sablon elrejtve lesz, amíg az opcionális ASP.NET és a webfejlesztési számítási feladat nincs telepítve.

Terminológia

Sok kifejezést tévesen szinonimaként használnak. Ez a szakasz ezen kifejezések némelyikét határozza meg, hogy a jelen cikkben szereplő szándékuk egyértelműbb legyen.

  • Háttérszolgáltatás: A BackgroundService típus.
  • Üzemeltetett szolgáltatás: Implementációk IHostedServicevagy IHostedService maga.
  • Hosszan futó szolgáltatás: Minden olyan szolgáltatás, amely folyamatosan fut.
  • Windows-szolgáltatás: A Windows szolgáltatás infrastruktúrája eredetileg .NET-keretrendszer-központú, de most már elérhető a .NET-en keresztül.
  • Feldolgozói szolgáltatás: A feldolgozói szolgáltatás sablonja.

Feldolgozói szolgáltatás sablonja

A Worker Service-sablon a .NET CLI-ben és a Visual Studióban érhető el. További információ: .NET CLI, dotnet new worker - template. A sablon egy és Worker egy Program osztályból áll.

using App.WorkerService;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<Worker>();

IHost host = builder.Build();
host.Run();

Az előző Program osztály:

  • Létrehoz egy HostApplicationBuilder.
  • Hívások AddHostedService a Worker üzemeltetett szolgáltatásként való regisztráláshoz.
  • A készítőtől készít egy buildet IHost .
  • Meghívja Run az host alkalmazást futtató példányt.

A sablon alapértelmezései

A Feldolgozó sablon alapértelmezés szerint nem engedélyezi a kiszolgálói szemétgyűjtést (GC), mivel számos tényező játszik szerepet a szükségesség meghatározásában. A hosszú ideig futó szolgáltatásokat igénylő összes forgatókönyvnek figyelembe kell vennie ennek az alapértelmezettnek a teljesítménybeli következményeit. A kiszolgálói csoportházirend-objektum engedélyezéséhez adja hozzá a ServerGarbageCollection csomópontot a projektfájlhoz:

<PropertyGroup>
    <ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>

Kompromisszumok és szempontok

Engedélyezve Disabled (Letiltva)
Hatékony memóriakezelés: Automatikusan visszanyeri a nem használt memóriát a memóriavesztés elkerülése és az erőforrás-használat optimalizálása érdekében. Jobb valós idejű teljesítmény: Elkerüli a késésre érzékeny alkalmazásokban a szemétgyűjtés által okozott esetleges szüneteltetéseket vagy megszakításokat.
Hosszú távú stabilitás: Segít a hosszú ideig futó szolgáltatások stabil teljesítményének fenntartásában azáltal, hogy hosszabb ideig kezeli a memóriát. Erőforrás-hatékonyság: Csökkentheti a processzor- és memóriaerőforrásokat az erőforrás-korlátozott környezetekben.
Kevesebb karbantartás: Minimalizálja a manuális memóriakezelés szükségességét, egyszerűsítve a karbantartást. Manuális memóriavezérlés: Részletes vezérlést biztosít a speciális alkalmazások memóriája felett.
Kiszámítható viselkedés: Hozzájárul az alkalmazások konzisztens és kiszámítható viselkedéséhez. Rövid élettartamú folyamatokhoz alkalmas: Minimalizálja a szemétgyűjtés többletterhelését a rövid élettartamú vagy rövid élettartamú folyamatokhoz.

A teljesítménnyel kapcsolatos szempontokról további információt a kiszolgálói GC-ben talál. A kiszolgálói GC konfigurálásával kapcsolatos további információkért lásd a kiszolgálói csoportházirend-konfigurációs példákat.

Feldolgozói osztály

Ami a Workersablont, egy egyszerű implementációt biztosít.

namespace App.WorkerService;

public sealed class Worker(ILogger<Worker> logger) : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
            await Task.Delay(1_000, stoppingToken);
        }
    }
}

Az előző osztály a implementálandó WorkerIHostedServiceosztály alosztályaBackgroundService. Ez BackgroundService egy abstract class , és az alosztályt kell implementálnia BackgroundService.ExecuteAsync(CancellationToken). A sablon implementációjában a ExecuteAsync hurkok másodpercenként egyszer futnak, és az aktuális dátumot és időt naplózzák, amíg a folyamat nem lesz jelezve a megszakításra.

A projektfájl

A Feldolgozó sablon a következő projektfájlra Sdktámaszkodik:

<Project Sdk="Microsoft.NET.Sdk.Worker">

További információ: .NET-projekt SDK-k.

NuGet-csomag

A Feldolgozó sablonon alapuló alkalmazások az SDK-t Microsoft.NET.Sdk.Worker használják, és kifejezetten hivatkoznak a Microsoft.Extensions.Hosting csomagra.

Tárolók és felhőadaptálás

A legtöbb modern .NET-számítási feladat esetén a tárolók életképes megoldást jelentenek. Ha hosszú ideig futó szolgáltatást hoz létre a Visual Studióban a Worker sablonból, a Docker-támogatás mellett is dönthet. Ezzel létrehoz egy Dockerfile-t , amely tárolóba helyezi a .NET-alkalmazást. A Dockerfile a rendszerképek létrehozásához szükséges utasítások készlete. A .NET-alkalmazások esetében a Dockerfile általában a megoldásfájl mellett található könyvtár gyökerében található.

# See https://aka.ms/containerfastmode to understand how Visual Studio uses this
# Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["background-service/App.WorkerService.csproj", "background-service/"]
RUN dotnet restore "background-service/App.WorkerService.csproj"
COPY . .
WORKDIR "/src/background-service"
RUN dotnet build "App.WorkerService.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "App.WorkerService.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "App.WorkerService.dll"]

Az előző Dockerfile-lépések a következők:

  • Az alaprendszerkép mcr.microsoft.com/dotnet/runtime:8.0 beállítása aliasként base.
  • A munkakönyvtár módosítása /appra.
  • Az build alias beállítása a mcr.microsoft.com/dotnet/sdk:8.0 képről.
  • A munkakönyvtár módosítása /src fájlra.
  • A tartalom másolása és a .NET-alkalmazás közzététele:
    • Az alkalmazás közzététele a dotnet publish paranccsal történik.
  • A .NET SDK-rendszerkép továbbítása (aliasbase).mcr.microsoft.com/dotnet/runtime:8.0
  • A közzétett buildkimenet másolása a /publish fájlból.
  • Annak a belépési pontnak a meghatározása, amely a következőre delegálható dotnet App.BackgroundService.dll: .

Tipp.

Az MCR a mcr.microsoft.com "Microsoft Container Registry" (Microsoft Container Registry) nevet jelöli, és a Microsoft konzorciális tárolókatalógusa a hivatalos Docker Hubból. A Microsoft syndicates tárolókatalógus-cikke további részleteket tartalmaz.

Ha a Dockert a .NET-feldolgozó szolgáltatás üzembehelyezési stratégiájaként célozza meg, a projektfájlban néhány szempont szerepel:

<Project Sdk="Microsoft.NET.Sdk.Worker">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>true</ImplicitUsings>
    <RootNamespace>App.WorkerService</RootNamespace>
    <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
    <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
  </ItemGroup>
</Project>

Az előző projektfájlban az elem a <DockerDefaultTargetOS> célként van meghatározva Linux . A Windows-tárolók célként való megcélzásához használja Windows inkább. A Microsoft.VisualStudio.Azure.Containers.Tools.Targets NuGet-csomag automatikusan hozzáadódik csomaghivatkozásként, amikor a Docker-támogatás ki van választva a sablonból.

A Dockerrel és a .NET-tel kapcsolatos további információkért tekintse meg a .NET-alkalmazások tárolóba helyezése című oktatóanyagot. Az Azure-ban történő üzembe helyezéssel kapcsolatos további információkért lásd : Oktatóanyag: Feldolgozói szolgáltatás üzembe helyezése az Azure-ban.

Fontos

Ha a Felhasználói titkos kódokat a Feldolgozó sablonnal szeretné használni, kifejezetten hivatkoznia kell a Microsoft.Extensions.Configuration.UserSecrets NuGet-csomagra.

Üzemeltetett szolgáltatás bővíthetősége

Az IHostedService interfész két módszert határoz meg:

Ez a két metódus életciklus-metódusként szolgál – a gazdagép indítása és leállítása során hívják őket.

Feljegyzés

Bármelyik vagy StopAsync metódus felülírásakor StartAsync meg kell hívnia az osztálymetódust, hogy awaitbase a szolgáltatás megfelelően induljon el és/vagy leálljon.

Fontos

Az interfész általános típusú paraméterkorlátozásként szolgál a AddHostedService<THostedService>(IServiceCollection) bővítménymetódushoz, ami azt jelenti, hogy csak implementációk engedélyezettek. Használhatja a megadott BackgroundService alosztályt, vagy teljes mértékben megvalósíthatja a sajátját.

Jelkiegészítés

A leggyakoribb forgatókönyvekben nem kell explicit módon jeleznie egy üzemeltetett szolgáltatás befejezését. Amikor a gazdagép elindítja a szolgáltatásokat, úgy vannak kialakítva, hogy addig fussanak, amíg a gazdagép le nem áll. Bizonyos esetekben azonban előfordulhat, hogy a szolgáltatás befejeződésekor a teljes gazdaalkalmazás befejezését kell jeleznie. A befejezés jelzéséhez vegye figyelembe a következő Worker osztályt:

namespace App.SignalCompletionService;

public sealed class Worker(
    IHostApplicationLifetime hostApplicationLifetime,
    ILogger<Worker> logger) : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        // TODO: implement single execution logic here.
        logger.LogInformation(
            "Worker running at: {Time}", DateTimeOffset.Now);

        await Task.Delay(1_000, stoppingToken);

        // When completed, the entire app host will stop.
        hostApplicationLifetime.StopApplication();
    }
}

Az előző kódban a ExecuteAsync metódus nem hurkol, és amikor befejeződött, meghívja IHostApplicationLifetime.StopApplication().

Fontos

Ez jelzi a gazdagépnek, hogy le kell állnia, és a gazdagép StopApplication hívása nélkül továbbra is határozatlan ideig fog futni.

További információkért lásd:

Lásd még