Düzenli Görevler ve Zamanlayıcılar
PeriodicTimer ve System.Threading.Timer ile yinelenen işleri zamanlayın, iptali sorunsuz şekilde yönetin.
Düzenli Görevler ve Zamanlayıcılar, CoddyKit'te ücretsiz bir C# Academy dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C# Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C# Academy kursu toplamda 4 dersten oluşur.
Yinelenen İşleri Zamanlama
Birçok arka plan hizmetinin sabit bir zamanlamayla, örneğin her 5 dakikada, her saat veya her gün çalışması gerekir. .NET bunun için çeşitli mekanizmalar sağlar: PeriodicTimer (modern), System.Threading.Timer (klasik) ve Quartz.NET (cron tabanlı).
PeriodicTimer: Modern Seçim
PeriodicTimer (.NET 6 ile tanıtılmıştır), async yöntemlerde kullanılmak üzere tasarlanmıştır. Geri çağırmalar olmadan tam zamanında tetiklenir ve iptal işlemiyle sorunsuz şekilde tümleşir.
public class MetricsCollectorService : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken ct)
{
using var timer = new PeriodicTimer(TimeSpan.FromMinutes(1));
while (await timer.WaitForNextTickAsync(ct))
{
// Runs every 60 seconds
await CollectMetricsAsync(ct);
}
// Loop exits cleanly when ct is cancelled
}
}PeriodicTimer ve Task.Delay Döngüsü
PeriodicTimer, Task.Delay döngüsünden daha iyidir: başlangıç zamanı + işleme süresi yerine başlangıç zamanından itibaren sabit aralıklarla tetiklenir ve çok sayıda yineleme boyunca zaman kaymasını önler.
// Task.Delay loop — drifts! (interval = delay + work time)
while (!ct.IsCancellationRequested)
{
await DoWorkAsync(ct); // takes 2 seconds
await Task.Delay(5000, ct); // actual period: 7 seconds
}
// PeriodicTimer — no drift
using var timer = new PeriodicTimer(TimeSpan.FromSeconds(5));
while (await timer.WaitForNextTickAsync(ct))
{
await DoWorkAsync(ct); // period is still 5 seconds from start
}System.Threading.Timer
System.Threading.Timer, geri çağırma kullanan klasik bir iş parçacığı havuzu zamanlayıcısıdır. Hem yinelenen hem de tek seferlik kipleri destekler. Dikkatli olun: geri çağırma, async desteği olmayan bir iş parçacığı havuzunda çalışır.
public class LegacyTimerService : BackgroundService, IDisposable
{
private Timer? _timer;
protected override Task ExecuteAsync(CancellationToken ct)
{
// Fire immediately then every 10 seconds
_timer = new Timer(DoWork, null,
dueTime: TimeSpan.Zero,
period: TimeSpan.FromSeconds(10));
return Task.CompletedTask;
}
private void DoWork(object? state)
{
// Runs on thread pool — avoid async void here
Console.WriteLine($"Timer fired: {DateTime.UtcNow}");
}
public override void Dispose() { _timer?.Dispose(); base.Dispose(); }
}Tek Seferlik Gecikmeli Çalıştırma
Tek seferlik gecikmeli çalıştırma için PeriodicTimer ile tek bir tik kullanın veya CancellationTokenSource.CancelAfter ile Task.Delay yöntemlerini birlikte kullanın.
// Run once after a delay
public async Task ScheduleOnceAsync(TimeSpan delay, Func<Task> action, CancellationToken ct)
{
await Task.Delay(delay, ct);
await action();
}
// Or with CancellationToken:
var cts = new CancellationTokenSource(TimeSpan.FromHours(1));
try
{
await Task.Delay(Timeout.Infinite, cts.Token);
}
catch (OperationCanceledException)
{
await RunScheduledJobAsync();
}PeriodicTimer ile Hata İşleme
Tek bir hatanın sonraki döngüde zamanlayıcının yeniden tik atmasını durdurmaması için her tikteki işi her zaman try/catch içine alın.
protected override async Task ExecuteAsync(CancellationToken ct)
{
using var timer = new PeriodicTimer(TimeSpan.FromMinutes(5));
while (await timer.WaitForNextTickAsync(ct))
{
try
{
await SyncInventoryAsync(ct);
}
catch (Exception ex)
{
// Log but don't crash — next tick will retry
_logger.LogError(ex, "Inventory sync failed");
}
}
}Saat Sınırlarına Hizalama
Belirli saatlerde çalıştırmak, örneğin her saat başında çalıştırmak için zamanlayıcıyı başlatmadan önce bir sonraki sınıra kadar olan başlangıç gecikmesini hesaplayın.
protected override async Task ExecuteAsync(CancellationToken ct)
{
// Wait until the next full hour
var now = DateTime.UtcNow;
var nextHour = now.Date.AddHours(now.Hour + 1);
var initialDelay = nextHour - now;
await Task.Delay(initialDelay, ct);
// Then tick every hour exactly
using var timer = new PeriodicTimer(TimeSpan.FromHours(1));
await RunJobAsync(ct); // run at the first tick
while (await timer.WaitForNextTickAsync(ct))
await RunJobAsync(ct);
}Eşzamanlı Tikleri Önleme
İşin bir zamanlayıcı döneminden uzun sürmesi mümkünse SemaphoreSlim ile eşzamanlı çalışmaya karşı koruma sağlayın veya iş hâlâ sürüyorsa tiki atlayın.
private readonly SemaphoreSlim _lock = new(1, 1);
protected override async Task ExecuteAsync(CancellationToken ct)
{
using var timer = new PeriodicTimer(TimeSpan.FromSeconds(30));
while (await timer.WaitForNextTickAsync(ct))
{
// Skip if previous tick is still running
if (!await _lock.WaitAsync(0, ct))
{
_logger.LogWarning("Skipping tick — previous still running");
continue;
}
try { await DoWorkAsync(ct); }
finally { _lock.Release(); }
}
}Dağıtık Hizmetler için Rastgele Gecikme
Bir hizmetin birden çok örneği aynı anda başladığında, başlangıç gecikmesine rastgele bir gecikme eklemek paylaşılan kaynaklarda oluşan yoğun istek sorunlarını önler.
protected override async Task ExecuteAsync(CancellationToken ct)
{
// Add jitter: 0-5 seconds random delay on startup
var jitter = TimeSpan.FromSeconds(Random.Shared.NextDouble() * 5);
await Task.Delay(jitter, ct);
using var timer = new PeriodicTimer(TimeSpan.FromMinutes(1));
while (await timer.WaitForNextTickAsync(ct))
await RunJobAsync(ct);
}Gerçek Dünya: Önbellek Yenileme Hizmeti
Dağıtık bir önbelleği her 10 dakikada bir yenileyen, rastgele gecikme ve hata kurtarma özelliklerine sahip dönemsel bir hizmet.
public class CacheRefreshService : BackgroundService
{
private readonly IServiceScopeFactory _factory;
private readonly ILogger<CacheRefreshService> _log;
protected override async Task ExecuteAsync(CancellationToken ct)
{
// Spread startups across instances
await Task.Delay(TimeSpan.FromSeconds(Random.Shared.Next(0, 30)), ct);
using var timer = new PeriodicTimer(TimeSpan.FromMinutes(10));
while (await timer.WaitForNextTickAsync(ct))
{
try
{
using var scope = _factory.CreateScope();
var cache = scope.ServiceProvider.GetRequiredService<ICacheService>();
await cache.RefreshAllAsync(ct);
_log.LogInformation("Cache refreshed at {Time}", DateTime.UtcNow);
}
catch (Exception ex) { _log.LogError(ex, "Cache refresh failed"); }
}
}
}Kısa Kontrol
Yinelenen görevlerde Task.Delay döngüsü yerine PeriodicTimer neden tercih edilir?
Özet: Dönemsel Görevler ve Zamanlayıcılar
Temel çıkarımlar:
PeriodicTimer: async, iptali dikkate alır, zaman kayması oluşturmaz — modern seçimdirSystem.Threading.Timer: geri çağırma tabanlıdır, eski kodlarla tümleştirme için uygundur- Hataların zamanlayıcıyı durdurmaması için her tikteki işi try/catch içine alın
- Dağıtık örneklerde yoğun istek sorununu önlemek için rastgele gecikme ekleyin
- Önceki tik hâlâ çalışıyorsa tiki atlamak için
SemaphoreSlimkullanın - Tikleri saat sınırlarıyla hizalamak için başlangıç gecikmesini hesaplayın
Yapay zeka eğitmeniyle C# öğren — ücretsiz
Tarayıcında gerçek kod yaz ve çalıştır, 7/24 yapay zeka eğitmeninden anında yardım al; web'de ya da uygulamada kaldığın yerden devam et.
- Kurslar
- 93
- Dersler
- 346
Sıkça Sorulan Sorular
“Düzenli Görevler ve Zamanlayıcılar” dersi ücretsiz mi?
Evet — “Düzenli Görevler ve Zamanlayıcılar” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C# Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C# Academy kursu toplamda 4 dersten oluşur.
“Düzenli Görevler ve Zamanlayıcılar” dersinde ne öğreneceğim?
PeriodicTimer ve System.Threading.Timer ile yinelenen işleri zamanlayın, iptali sorunsuz şekilde yönetin. C# Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
C# Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te C# Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.
“Düzenli Görevler ve Zamanlayıcılar” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu C# Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her C# Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- IHostedService ve BackgroundService
- Worker Service Projeleri
- Düzenli Görevler ve Zamanlayıcılar
- Quartz.NET Zamanlanmış İşleri