Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Uzun süre çalışan hizmetler oluşturmanın çeşitli nedenleri vardır:
- Yoğun CPU kullanan verileri işleme.
- İş öğelerini arka planda kuyruğa alma.
- Zamanlamaya uygun olarak zaman tabanlı bir işlem gerçekleştirme.
Arka plan hizmeti işleme genellikle bir kullanıcı arabirimi (UI) içermez, ancak bunların etrafında kullanıcı arabirimleri oluşturulabilir. .NET Framework ile ilk günlerde, Windows geliştiricileri bu amaçlar için Windows Hizmetleri oluşturabilirdi. Artık .NET ile, BackgroundServiceuygulaması olan IHostedServicekullanabilir veya kendi uygulamanızı uygulayabilirsiniz.
.NET ile artık Windows ile sınırlı değilsiniz. Platformlar arası arka plan hizmetleri geliştirebilirsiniz. Barındırılan hizmetler, günlük kaydı, yapılandırma ve bağımlılık enjeksiyonu (DI) için hazırdır. Bunlar, kitaplıkların uzantı paketinin bir parçasıdır; yani genel ana bilgisayarile çalışan tüm .NET iş yükleri için temeldir.
Önemli
.NET SDK'sını yüklemek Microsoft.NET.Sdk.Worker ve çalışan şablonunu da yükler. Başka bir deyişle, .NET SDK'sını yükledikten sonra dotnet new worker komutunu kullanarak yeni bir çalışan oluşturabilirsiniz. Visual Studio kullanıyorsanız, isteğe bağlı ASP.NET ve web geliştirme iş yükü yüklenene kadar şablon gizlenir.
Terminoloji
Birçok terim yanlışlıkla eş anlamlı olarak kullanılır. Bu bölüm, bu makaledeki amaçlarını daha belirgin hale getirmek için bu terimlerden bazılarını tanımlar.
- Arka Plan Hizmeti: BackgroundService türü.
- Barındırılan Hizmet: IHostedServiceuygulamaları veya IHostedService'in kendisi.
- Uzun Süre Çalışan Hizmet: Kesintisiz çalışan herhangi bir hizmet.
- Windows Hizmeti: Windows Hizmeti altyapısı, başlangıçta .NET Framework merkezlidir ancak artık .NET üzerinden erişilebilir.
- Çalışan Hizmeti: Çalışan Hizmeti şablonu.
Çalışan Hizmeti şablonu
Çalışan Hizmeti şablonu .NET CLI ve Visual Studio'da kullanılabilir. Daha fazla bilgi için bkz. .NET CLI , dotnet new worker - şablon. Şablon bir Program ve Worker sınıfından oluşur.
using App.WorkerService;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<Worker>();
IHost host = builder.Build();
host.Run();
Önceki Program sınıfı:
- HostApplicationBuilder oluşturur.
-
AddHostedService,
Worker'i barındırılan hizmet olarak kaydetmek için çağırır. - Oluşturucudan bir IHost oluşturur.
- Uygulamayı çalıştıran
Runörneğindehostçağırır.
Şablon varsayılanları
Çalışan şablonu varsayılan olarak sunucu çöp toplamayı (GC) etkinleştirmez çünkü gerekliliğini belirlemede rol oynayan çok sayıda faktör vardır. Uzun süre çalışan hizmetler gerektiren tüm senaryolar bu varsayılanın performans üzerindeki etkilerini dikkate almalıdır. Sunucu GC'yi etkinleştirmek için ServerGarbageCollection düğümünü proje dosyasına ekleyin:
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>
Dengeler ve dikkat edilmesi gerekenler
| Etkinleştirildi | Sakat |
|---|---|
| Verimli bellek yönetimi: Bellek sızıntılarını önlemek ve kaynak kullanımını iyileştirmek için kullanılmayan belleği otomatik olarak geri alır. | Geliştirilmiş gerçek zamanlı performans: Gecikme süresine duyarlı uygulamalarda atık toplamanın neden olduğu olası duraklamaları veya kesintileri önler. |
| Uzun vadeli kararlılık: Uzun süreler boyunca belleği yöneterek uzun süre çalışan hizmetlerde kararlı performansın korunmasına yardımcı olur. | Kaynak verimliliği: Kaynak kısıtlanmış ortamlarda CPU ve bellek kaynaklarından tasarruf edebilir. |
| Daha az bakım: El ile bellek yönetimi gereksinimini en aza indirerek bakımı basitleştirir. | El ile bellek denetimi: Özel uygulamalar için bellek üzerinde ayrıntılı denetim sağlar. |
| Öngörülebilir davranış: Tutarlı ve öngörülebilir uygulama davranışına katkıda bulunur. | Kısa süreli işlemler için uygundur: Kısa süreli veya kısa ömürlü işlemler için çöp toplama yükünü en aza indirir. |
Performansla ilgili dikkat edilmesi gerekenler hakkında daha fazla bilgi için bkz. Server GC. Sunucu GC'sini yapılandırma hakkında daha fazla bilgi için bkz. Sunucu GC yapılandırma örnekleri.
Çalışan sınıfı
Workergelince, şablon basit bir uygulama sağlar.
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);
}
}
}
Yukarıdaki Worker sınıfı, BackgroundServiceuygulayan IHostedServicealt sınıfıdır.
BackgroundService bir abstract class ve alt sınıfın BackgroundService.ExecuteAsync(CancellationToken) uygulamasını gerektirir. Şablon uygulamasında, ExecuteAsync her saniyede bir kez döngü yapar ve işlemin iptal edilmesi için sinyal verilene kadar geçerli tarih ve saati günlüğe kaydeder.
Proje dosyası
Çalışan şablonu, Sdkaşağıdaki proje dosyasına dayanır:
<Project Sdk="Microsoft.NET.Sdk.Worker">
Daha fazla bilgi için bkz. .NET proje SDK'ları.
NuGet paketi
Çalışan şablonunu temel alan bir uygulama Microsoft.NET.Sdk.Worker SDK'sını kullanır ve Microsoft.Extensions.Hosting paketine açık bir paket başvurusuna sahiptir.
Kapsayıcılar ve buluta uyarlanabilirlik
Çoğu modern .NET iş yükünde kapsayıcılar uygulanabilir bir seçenektir. Visual Studio'da Çalışan şablonundan uzun süre çalışan bir hizmet oluştururken, Docker desteğini kabul edebilirsiniz. Bunu yaptığınızda ,NET uygulamanızı kapsayıcıya alan bir Dockerfile oluşturulur. Dockerfile, görüntü oluşturmaya yönelik yönergeler kümesidir. .NET uygulamaları için Dockerfile genellikle bir çözüm dosyasının yanındaki dizinin kökünde yer alır.
# 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"]
Yukarıdaki Dockerfile adımları şunlardır:
-
mcr.microsoft.com/dotnet/runtime:8.0taban görüntüsünübasetakma adı olarak ayarlama. - Çalışma dizinini /appolarak değiştirme.
-
buildtakma adınımcr.microsoft.com/dotnet/sdk:8.0görüntüsünden ayarlama. - Çalışma dizinini /srcolarak değiştirme.
- İçeriği kopyalama ve .NET uygulamasını yayımlama:
- Uygulama,
dotnet publishkomutu kullanılarak yayımlanır.
- Uygulama,
-
mcr.microsoft.com/dotnet/runtime:8.0'dan .NET SDK görüntüsünü geçirme (basediğer adı). - /publishkonumundan yayımlanan derleme çıktısını kopyalayın.
- Giriş noktasının tanımlanması,
dotnet App.BackgroundService.dll'a havale edilmesiyle.
Bahşiş
mcr.microsoft.com'daki MCR, "Microsoft Container Registry" anlamına gelir ve Microsoft'un resmi Docker hub'ından gelen genel kapsayıcı kataloğudur.
Microsoft sindikalar kapsayıcı kataloğu makalesi ilave detaylar içerir.
Docker'ı .NET Çalışan Hizmetiniz için dağıtım stratejisi olarak hedeflediğinizde, proje dosyasında dikkat edilmesi gereken birkaç nokta vardır:
<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="9.0.7" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
</ItemGroup>
</Project>
Önceki proje dosyasında, <DockerDefaultTargetOS> öğesi hedefi olarak Linux belirtir. Windows kapsayıcılarını hedeflemek için bunun yerine Windows kullanın.
Microsoft.VisualStudio.Azure.Containers.Tools.Targets NuGet paketi, şablondan Docker desteği seçildiğinde otomatik olarak paket başvurusu olarak eklenir.
.NET ile Docker hakkında daha fazla bilgi için bkz. Eğitimi: .NET uygulamasını kapsayıcılı hale getirme. Azure'a dağıtma hakkında daha fazla bilgi için bkz. Azure'a Çalışan Hizmeti Dağıtma Öğretici.
Önemli
Çalışan şablonuyla Kullanıcı Sırları kullanmak istiyorsanız, Microsoft.Extensions.Configuration.UserSecrets NuGet paketine açıkça referans vermeniz gerekir.
Barındırılan Hizmet genişletilebilirliği
IHostedService arabirimi iki yöntem tanımlar:
Bu iki yöntem, yaşam döngüsü yöntemleri olarak hizmet eder. Bunlar sırasıyla konak başlatma ve durdurma olayları sırasında çağrılır.
Not
StartAsync veya StopAsync yöntemlerini geçersiz kıldığınızda, hizmetin düzgün şekilde başlatılması ve/veya kapatılması için await sınıf yöntemi çağırılmalı ve base edilmelidir.
Önemli
Arabirim, AddHostedService<THostedService>(IServiceCollection) uzantısı yönteminde genel tür parametre kısıtlaması görevi görür, yani yalnızca uygulamalara izin verilir. BackgroundService'ı verilen bir alt sınıfla kullanmakta veya tamamen kendi çözümünüzü gerçekleştirmekte özgürsünüz.
Sinyalin tamamlanması
Çoğu yaygın senaryoda, barındırılan bir hizmetin tamamlanmasını açıkça işaret etmeniz gerekmez. Sunucu hizmetleri başlattığında, sunucu durdurulana kadar çalışacak şekilde tasarlanmıştır. Ancak bazı senaryolarda, hizmet tamamlandığında konak uygulamasının tamamının tamamlanmasının sinyalini vermeniz gerekebilir. Tamamlanma sinyali vermek için aşağıdaki Worker sınıfını göz önünde bulundurun:
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();
}
}
Önceki kodda, BackgroundService.ExecuteAsync(CancellationToken) yöntemi döngü yapmaz ve tamamlandığında IHostApplicationLifetime.StopApplication()çağırır.
Önemli
Bu, konağa durması gerektiğini bildirir ve StopApplication bu çağrı olmadan konak süresiz olarak çalışmaya devam eder. Kısa süreli bir barındırılan hizmeti (bir kez çalıştırma senaryosu) çalıştırmak ve Çalışan şablonunu kullanmak istiyorsanız, konağın durması için StopApplication çağrısını yapmanız gerekir.
Daha fazla bilgi için bkz:
- .NET Genel Konağı : IHostApplicationLifetime
- .NET Genel Ana Bilgisayarı : Ana Bilgisayarın Kapanışı
- .NET Genel Ana Bilgisayarı : Kapatma işlemini barındırma
Alternatif yaklaşım
Bağımlılık ekleme, günlüğe kaydetme ve yapılandırma gerektiren kısa süreli bir uygulama için Çalışan şablonu yerine .NET Genel Ana Bilgisayarı'nı kullanın. Böylece, bu özellikleri Worker sınıfı olmadan kullanmanıza olanak tanır. Genel konağı kullanan kısa ömürlü bir uygulamanın basit bir örneği aşağıdaki gibi bir proje dosyası tanımlayabilir:
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net9.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 Sınıfı aşağıdakine benzer olabilir:
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
}
Yukarıdaki kod, işin çalıştırılacak mantığını içeren özel bir sınıf olan bir hizmet oluşturur JobRunner .
RunAsync yöntemi JobRunner üzerinde çağrılır ve başarıyla tamamlanırsa uygulama 0 döndürür. İşlenmeyen bir özel durum oluşursa hatayı günlüğe kaydeder ve 1 değerini geri döndürür.
Bu basit senaryoda sınıfı JobRunner aşağıdaki gibi görünebilir:
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.");
}
}
Yönteme RunAsync gerçek mantık eklemeniz gerektiği açıktır, ancak bu örnek, bir sınıfa gerek kalmadan ve konağın tamamlanmasını açıkça işaret etmeye gerek kalmadan kısa süreli bir Worker uygulama için genel konağın nasıl kullanılacağını gösterir.
Ayrıca bkz.
- BackgroundService alt sınıf dersleri:
- Özel IHostedService uygulaması: