Služby pracovních procesů v .NET
Existuje mnoho důvodů pro vytváření dlouhotrvajících služeb, například:
- Zpracování dat náročných na procesor
- Řazení pracovních položek do fronty na pozadí
- Provádění operace založené na čase podle plánu.
Zpracování služby na pozadí obvykle nezahrnuje uživatelské rozhraní, ale uživatelská rozhraní je možné kolem nich sestavit. V prvních dnech s rozhraním .NET Framework mohou vývojáři windows pro tyto účely vytvářet služby Systému Windows. Nyní s .NET můžete použít BackgroundService, což je implementace IHostedService, nebo implementovat vlastní.
S .NET už nejste omezeni na Windows. Můžete vyvíjet multiplatformní služby na pozadí. Hostované služby jsou připravené pro protokolování, konfiguraci a injektáž závislostí (DI). Jsou součástí sady rozšíření knihoven, což znamená, že jsou zásadní pro všechny úlohy .NET, které pracují s obecným hostitelem.
Důležité
Instalace sady .NET SDK také nainstaluje Microsoft.NET.Sdk.Worker
šablonu pracovního procesu. Jinými slovy, po instalaci sady .NET SDK můžete vytvořit nový pracovní proces pomocí příkazu dotnet new worker . Pokud používáte Visual Studio, šablona se skryje, dokud se nenainstaluje volitelná ASP.NET a úloha vývoje webu.
Terminologie
Mnoho termínů se omylem používá jako synonymum. Tato část definuje některé z těchto termínů, aby bylo jejich záměr v tomto článku zjevnější.
- Služba na pozadí: Typ BackgroundService .
- Hostovaná služba: Implementace IHostedServicenebo IHostedService samotné.
- Dlouhotrvající služba: Jakákoli služba, která běží nepřetržitě.
- Služba Systému Windows: Infrastruktura služeb systému Windows, která byla původně zaměřena na rozhraní .NET Framework, ale nyní je přístupná prostřednictvím .NET.
- Pracovní služba: Šablona pracovní služby .
Šablona služby pracovního procesu
Šablona pracovní služby je k dispozici v rozhraní .NET CLI a sadě Visual Studio. Další informace najdete v tématu .NET CLI– dotnet new worker
šablona. Šablona se skládá z třídy Program
a Worker
třídy.
using App.WorkerService;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<Worker>();
IHost host = builder.Build();
host.Run();
Předchozí Program
třída:
- Vytvoří .HostApplicationBuilder
- Volání AddHostedService pro registraci
Worker
jako hostované služby - Vytvoří z tvůrce.IHost
host
ZavoláRun
instanci, která spustí aplikaci.
Výchozí hodnoty šablony
Šablona Pracovního procesu ve výchozím nastavení nepovoluje uvolňování paměti serveru( GC), protože existuje mnoho faktorů, které hrají roli při určování jeho potřeby. Všechny scénáře, které vyžadují dlouhotrvající služby, by měly zvážit dopad na výkon tohoto výchozího nastavení. Pokud chcete povolit GC serveru, přidejte ServerGarbageCollection
uzel do souboru projektu:
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>
Kompromisy a aspekty
Povolený | Disabled |
---|---|
Efektivní správa paměti: Automaticky uvolní nevyužitou paměť, aby se zabránilo nevrácené paměti a optimalizovalo využití prostředků. | Vylepšený výkon v reálném čase: Zabraňuje potenciálním pozastavením nebo přerušením způsobeným uvolňováním paměti v aplikacích citlivých na latenci. |
Dlouhodobá stabilita: Pomáhá udržovat stabilní výkon v dlouhodobých službách tím, že spravuje paměť v delších obdobích. | Efektivita prostředků: Může šetřit prostředky procesoru a paměti v prostředích s omezenými prostředky prostředků. |
Omezená údržba: Minimalizuje potřebu ruční správy paměti a zjednodušuje údržbu. | Ruční řízení paměti: Poskytuje jemně odstupňovanou kontrolu nad pamětí pro specializované aplikace. |
Předvídatelné chování: Přispívá k konzistentnímu a předvídatelnému chování aplikace. | Vhodné pro krátkodobé procesy: Minimalizuje režii uvolňování paměti pro krátkodobé nebo dočasné procesy. |
Další informace týkající se aspektů výkonu naleznete v tématu Server GC. Další informace o konfiguraci serveru GC naleznete v příkladech konfigurace serveru GC.
Worker – třída
Worker
Šablona poskytuje jednoduchou implementaci.
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);
}
}
}
Předchozí Worker
třída je podtřída BackgroundService, která implementuje IHostedService. Jedná se BackgroundService o abstract class
podtřídu a vyžaduje, aby implementovala BackgroundService.ExecuteAsync(CancellationToken)podtřídu . V implementaci ExecuteAsync
šablony smyčky jednou za sekundu zaznamenává aktuální datum a čas, dokud se proces nezruší.
Soubor projektu
Šablona pracovního procesu spoléhá na následující soubor Sdk
projektu:
<Project Sdk="Microsoft.NET.Sdk.Worker">
Další informace najdete v tématu Sady SDK projektu .NET.
Balíček NuGet
Aplikace založená na šabloně Pracovního procesu používá Microsoft.NET.Sdk.Worker
sadu SDK a obsahuje explicitní odkaz na balíček Microsoft.Extensions.Hosting .
Kontejnery a přizpůsobitelnost cloudu
U většiny moderních úloh .NET jsou kontejnery realizovatelnou možností. Při vytváření dlouhotrvající služby ze šablony pracovního procesu v sadě Visual Studio se můžete přihlásit k podpoře Dockeru. Tím se vytvoří soubor Dockerfile , který kontejnerizuje vaši aplikaci .NET. Soubor Dockerfile je sada instrukcí pro sestavení image. V případě aplikací .NET se soubor Dockerfile obvykle nachází v kořenovém adresáři vedle souboru řešení.
# 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"]
Mezi předchozí kroky souboru Dockerfile patří:
- Nastavení základní image z
mcr.microsoft.com/dotnet/runtime:8.0
aliasubase
. - Změna pracovního adresáře na /app
- Nastavení aliasu
build
z obrázkumcr.microsoft.com/dotnet/sdk:8.0
- Změna pracovního adresáře na /src
- Kopírování obsahu a publikování aplikace .NET:
- Aplikace se publikuje pomocí
dotnet publish
příkazu.
- Aplikace se publikuje pomocí
- Přenos image sady .NET SDK z
mcr.microsoft.com/dotnet/runtime:8.0
(aliasubase
) - Kopírování publikovaného výstupu sestavení z /publish
- Definování vstupního bodu, na který delegáti .
dotnet App.BackgroundService.dll
Tip
MCR mcr.microsoft.com
je zkratka pro Microsoft Container Registry a je syndikovaný katalog kontejnerů Microsoftu z oficiálního centra Dockeru. Článek o syndikaci katalogu kontejnerů Microsoftu obsahuje další podrobnosti.
Když cílíte na Docker jako strategii nasazení pro službu pracovního procesu .NET, je v souboru projektu potřeba vzít v úvahu několik aspektů:
<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.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
</ItemGroup>
</Project>
V předchozím souboru <DockerDefaultTargetOS>
projektu prvek určuje Linux
jako cíl. Pokud chcete cílit na kontejnery Windows, použijte Windows
místo toho. Balíček Microsoft.VisualStudio.Azure.Containers.Tools.Targets
NuGet se automaticky přidá jako odkaz na balíček při výběru podpory Dockeru ze šablony.
Další informace o Dockeru s .NET najdete v kurzu : Kontejnerizace aplikace .NET. Další informace o nasazení do Azure najdete v kurzu : Nasazení pracovní služby do Azure.
Důležité
Pokud chcete využít tajné kódy uživatele se šablonou Pracovního procesu, budete muset explicitně odkazovat na Microsoft.Extensions.Configuration.UserSecrets
balíček NuGet.
Rozšiřitelnost hostované služby
Rozhraní IHostedService definuje dvě metody:
Tyto dvě metody slouží jako metody životního cyklu – volají se během spouštění a zastavování událostí hostitele.
Poznámka:
Při přepsání buď StartAsync nebo StopAsync metod, je nutné volat a await
metodu base
třídy, aby se zajistilo, že služba spustí nebo vypne správně.
Důležité
Rozhraní slouží jako omezení parametru obecného typu pro metodu AddHostedService<THostedService>(IServiceCollection) rozšíření, což znamená, že jsou povoleny pouze implementace. Můžete bezplatně používat podtřídu BackgroundService nebo implementovat vlastní.
Dokončení signálu
Ve většině běžných scénářů nemusíte explicitně signalizovat dokončení hostované služby. Když hostitel spustí služby, jsou navržené tak, aby běžely, dokud se hostitel nezastaví. V některých scénářích ale možná budete muset po dokončení služby signalizovat dokončení celé hostitelské aplikace. Pokud chcete signalizovat dokončení, zvažte následující Worker
třídu:
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();
}
}
V předchozím kódu metoda neprovádí smyčku ExecuteAsync
a po dokončení volání IHostApplicationLifetime.StopApplication().
Důležité
To bude signalizovat hostiteli, že by se měl zastavit, a bez tohoto volání StopApplication
hostitele bude nadále běžet neomezeně dlouho.
Další informace naleznete v tématu:
- Obecný hostitel .NET: IHostApplicationLifetime
- Obecný hostitel .NET: Vypnutí hostitele
- Obecný hostitel .NET: Proces vypnutí hostování