Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
A hosszú ideig futó szolgáltatások létrehozásának számos oka van, például:
- Processzorigényes adatok feldolgozása.
- Munkaelemek sorba állítása 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 BackgroundService, amely a IHostedServiceimplementációja, 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önyvtárbővítmény-csomag részei, ami azt jelenti, hogy elengedhetetlenek minden .NET terheléshez, amely a általános gazdagéppelműködik.
Fontos
A .NET SDK telepítése a Microsoft.NET.Sdk.Worker és a feldolgozósablont is telepíti. Más szóval a .NET SDK telepítése után létrehozhat egy új feldolgozót a dotnet új feldolgozó paranccsal. 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ípusa.
- Üzemeltetett szolgáltatás: A IHostedServiceimplementációi vagy maga a IHostedService.
- hosszan futó szolgáltatás: Minden olyan szolgáltatás, amely folyamatosan fut.
- Windows Service: A Windows Service-infrastruktúra, amely eredetileg .NET-keretrendszer-központú, de most már elérhető a .NET-en keresztül.
- Munkás Szolgáltatás: A Munkás Szolgáltatás sablon.
Munka szolgáltatás sablon
A Worker Service-sablon a .NET CLI-ben és a Visual Studióban érhető el. További információ: .NET CLI, dotnet new worker – sablon. A sablon egy Program és Worker 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.
- Meghívja a AddHostedService-t, hogy regisztrálja a
Worker-et üzemeltetett szolgáltatásként. - Létrehoz egy IHost-t az építőből.
- Meghívja
Runaz alkalmazást futtatóhost-példányon.
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 szerver GC engedélyezéséhez adja hozzá a ServerGarbageCollection csomópontot a projektfájlhoz.
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>
Kompromisszumok és szempontok
| Engedélyezve | Fogyatékos |
|---|---|
| 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 az ilyen folyamatok esetén. |
A teljesítménnyel kapcsolatos további információkért lásd szerver GC. A kiszolgálói csoportházirend-objektumok konfigurálásával kapcsolatos további információkért lásd kiszolgálói csoportházirend-konfigurációs példákat.
Feldolgozói osztály
Ami a Worker-t illeti, a sablon 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ő Worker osztály a BackgroundServicealosztálya , amely IHostedServiceimplementál. A BackgroundService egy abstract class, és megköveteli az alosztálytól a BackgroundService.ExecuteAsync(CancellationToken)implementálását. A sablon implementációjában a ExecuteAsync másodpercenként egyszer ismétlődik ciklusban, az aktuális dátumot és időt naplózva, amíg a folyamat jelzést nem kap a megszakításra.
A projektfájl
A Feldolgozó sablon a következő projektfájlra támaszkodik Sdk:
<Project Sdk="Microsoft.NET.Sdk.Worker">
További információ: .NET-projekt SDK-k.
NuGet-csomag
A Feldolgozó sablonon alapuló alkalmazás a Microsoft.NET.Sdk.Worker SDK-t használja, és explicit csomaghivatkozással rendelkezik 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, akkor Docker-támogatás. Ezzel létrehoz egy Dockerfile, 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 melletti 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@sha256:e6b552fd7a0302e4db30661b16537f7efcdc0b67790a47dbf67a5e798582d3a5 AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:8.0@sha256:35792ea4ad1db051981f62b313f1be3b46b1f45cadbaa3c288cd0d3056eefb83 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 alapkép beállítása a
mcr.microsoft.com/dotnet/runtime:8.0-rólbasealias néven. - A munkakönyvtár megváltoztatása /app.
- A
buildalias beállítása amcr.microsoft.com/dotnet/sdk:8.0képből. - A munkakönyvtár módosítása /src.
- A tartalom másolása és a .NET-alkalmazás közzététele:
- Az alkalmazás közzététele a
dotnet publishparanccsal történik.
- Az alkalmazás közzététele a
- A .NET SDK kép újrétegezése a
mcr.microsoft.com/dotnet/runtime:8.0-ról (abasealias). - A közzétett build kimenet másolása a /publish.
- A belépési pont meghatározása, amely a
dotnet App.BackgroundService.dll-ra delegál.
Tipp
A mcr.microsoft.com MCR a "Microsoft Container Registry" rövidítése, amely a Microsoft szindikált konténerkatalógusa a hivatalos Docker hubról. A Microsoft tárolókatalógus című cikk 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>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<RootNamespace>App.WorkerService</RootNamespace>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.7" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
</ItemGroup>
</Project>
Az előző projektfájlban a <DockerDefaultTargetOS> elem a Linux határozza meg célként. Inkább a Windows-tartályok célzásához használja a Windows. A Microsoft.VisualStudio.Azure.Containers.Tools.Targets NuGet-csomag automatikusan hozzáadódik csomaghivatkozásként, amikor a sablonból a Docker-támogatás kerül kiválasztásra.
A Dockerrel és a .NET-tel kapcsolatos további információkért lásd oktatóanyagot: .NET-alkalmazás tárolóba helyezése. Az Azure-ban való üzembe helyezésről további információt a oktatóanyagban talál: Feldolgozó szolgáltatás üzembe helyezése az Azure-ban.
Fontos
Ha a Felhasználói titkok funkciót szeretné használni a Worker sablonnal, akkor kifejezetten hivatkoznia kell a Microsoft.Extensions.Configuration.UserSecrets NuGet-csomagra.
Üzemeltetett szolgáltatás bővíthetősége
A IHostedService felület két módszert határoz meg:
Ez a két módszer életciklus- metódusként szolgál – ezeket a host indítási és leállítási eseményei során hívjuk meg.
Jegyzet
A StartAsync vagy StopAsync metódusok felülírásakor meg kell hívnia és await a base osztálymetódust, hogy a szolgáltatás megfelelően elinduljon és/vagy leálljon.
Fontos
Az interfész általános típusú paraméterkorlátké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-t egy alosztállyal, vagy teljesen megvalósíthatja a sajátját.
Jelzés befejezése
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 BackgroundService.ExecuteAsync(CancellationToken) metódus nem ismétlődik, és ha elkészült, meghívja a IHostApplicationLifetime.StopApplication()metódust.
Fontos
Ez jelzi a gazdagépnek, hogy le kell állnia, és a StopApplication hívás nélkül a gazdagép továbbra is határozatlan ideig fog futni. Ha rövid időre szóló üzemeltetett szolgáltatást szeretne futtatni (egyszeri futtatási alkalommal), és a Worker sablont szeretné használni, akkor fel kell hívnia a StopApplication függvényt a gazdagép leállításához.
További információ:
- .NET Generikus Hoszt: IHostApplicationLifetime
- .NET Általános gazda: A gazdagép leállítása
- .NET Generic Host: A host leállítási folyamata
Alternatív megközelítés
A függőségi injekciót, naplózást és konfigurációt igénylő rövid életű alkalmazásokhoz használja a Worker sablon helyett a .NET Általános gazdagépet. Így az osztály nélkül is használhatja ezeket a Worker funkciókat. Az általános gazdagépet használó rövid élettartamú alkalmazások egyszerű példája az alábbihoz hasonló projektfájlt definiálhat:
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<RootNamespace>ShortLived.App</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.1" />
</ItemGroup>
</Project>
Program Az osztály a következőhöz hasonlóan nézhet ki:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddSingleton<JobRunner>();
using var host = builder.Build();
try
{
var runner = host.Services.GetRequiredService<JobRunner>();
await runner.RunAsync();
return 0; // success
}
catch (Exception ex)
{
var logger = host.Services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "Unhandled exception occurred during job execution.");
return 1; // failure
}
Az előző kód létrehoz egy JobRunner szolgáltatást, amely egy egyéni osztály, amely tartalmazza a feladat futtatásához szükséges logikát. A RunAsync metódus meghívódik a JobRunner-en, és ha sikeresen befejeződik, az alkalmazás visszaadja 0. Ha nem kezelt kivétel történik, naplózza a hibát, és visszaadja 1.
Ebben az egyszerű forgatókönyvben az osztály a JobRunner következőképpen nézhet ki:
using Microsoft.Extensions.Logging;
internal sealed class JobRunner(ILogger<JobRunner> logger)
{
public async Task RunAsync()
{
logger.LogInformation("Starting job...");
// Simulate work
await Task.Delay(1000);
// Simulate failure
// throw new InvalidOperationException("Something went wrong!");
logger.LogInformation("Job completed successfully.");
}
}
Nyilvánvalóan valódi logikát kell hozzáadnia a RunAsync metódushoz, de ez a példa bemutatja, hogyan használhatja a generikus gazdagépet rövid élettartamú alkalmazásokhoz anélkül, hogy szükség lenne egy Worker osztályra, és anélkül, hogy explicit módon jelezni kellene a gazdagép befejezését.
Lásd még:
-
BackgroundService alosztály oktatóanyagai:
- Sor szolgáltatás létrehozása a .NET-ben
-
Hatókör szolgáltatások használata egy
BackgroundService-en belül a .NET--ben -
BackgroundServicehasználatával
- Egyéni IHostedService implementáció: