日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

.net core 基于 IHostedService 实现定时任务

發布時間:2023/12/4 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .net core 基于 IHostedService 实现定时任务 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

.net core 基于 IHostedService 實現定時任務

Intro

從 .net core 2.0 開始,開始引入 IHostedService,可以通過 IHostedService 來實現后臺任務,但是只能在 WebHost 的基礎上使用。從 .net core 2.1 開始微軟引入通用主機( GenericHost),使得我們可以在不使用 Web 的情況下,也可以使用 IHostedService 來實現 定時任務/Windows服務/后臺任務,并且引入了一個 BackgroundService 抽象類來更方便的創建后臺任務。

IHostedService

IHostedService 后臺任務的執行與應用程序(就此而言,為主機或微服務)的生存期相協調。當應用程序啟動時注冊任務,當應用程序關閉時,有機會執行某些正常操作或清理。

始終可以啟動后臺線程來運行任何任務,而無需使用 IHostedService。不同之處就在于應用的關閉時間,此時會直接終止線程,而沒有機會執行正常的清理操作。

當注冊 IHostedService 時,.NET Core 會在應用程序啟動和停止期間分別調用 IHostedService 類型的 StartAsync()StopAsync() 方法。具體而言,即在服務器已啟動并已觸發 IApplicationLifetime.ApplicationStarted 后調用 start。

  • namespace Microsoft.Extensions.Hosting

  • {

  • //

  • // Summary:

  • // Defines methods for objects that are managed by the host.

  • public interface IHostedService

  • {

  • //

  • // Summary:

  • // Triggered when the application host is ready to start the service.

  • Task StartAsync(CancellationToken cancellationToken);

  • //

  • // Summary:

  • // Triggered when the application host is performing a graceful shutdown.

  • Task StopAsync(CancellationToken cancellationToken);

  • }

  • }

  • 可以從頭開始創建自定義托管服務類并實現 IHostedService,因為在使用 .NET Core 2.0 時需執行這些操作。

    但是,由于大多數后臺任務在取消令牌管理和其他典型操作方面都有類似的需求,因此 .net core 2.1 有一個非常方便且可以從中進行派生的抽象基類, BackgroundService 定義如下:

  • // Copyright (c) .NET Foundation. Licensed under the Apache License, Version 2.0.

  • /// <summary>

  • /// Base class for implementing a long running <see cref="IHostedService"/>.

  • /// </summary>

  • public abstract class BackgroundService : IHostedService, IDisposable

  • {

  • private Task _executingTask;

  • private readonly CancellationTokenSource _stoppingCts =

  • new CancellationTokenSource();


  • protected abstract Task ExecuteAsync(CancellationToken stoppingToken);


  • public virtual Task StartAsync(CancellationToken cancellationToken)

  • {

  • // Store the task we're executing

  • _executingTask = ExecuteAsync(_stoppingCts.Token);


  • // If the task is completed then return it,

  • // this will bubble cancellation and failure to the caller

  • if (_executingTask.IsCompleted)

  • {

  • return _executingTask;

  • }


  • // Otherwise it's running

  • return Task.CompletedTask;

  • }


  • public virtual async Task StopAsync(CancellationToken cancellationToken)

  • {

  • // Stop called without start

  • if (_executingTask == null)

  • {

  • return;

  • }


  • try

  • {

  • // Signal cancellation to the executing method

  • _stoppingCts.Cancel();

  • }

  • finally

  • {

  • // Wait until the task completes or the stop token triggers

  • await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));

  • }


  • }


  • public virtual void Dispose()

  • {

  • _stoppingCts.Cancel();

  • }

  • }

  • 實現一個簡單的后臺定時任務

    基于上面的信息,我們可以基于 IHostedService 實現一個簡單的后臺定時任務服務,

  • public abstract class ScheduedService : IHostedService, IDisposable

  • {

  • private readonly Timer _timer;

  • private readonly TimeSpan _period;

  • protected readonly ILogger Logger;


  • protected ScheduedService(TimeSpan period, ILogger logger)

  • {

  • Logger = logger;

  • _period = period;

  • _timer = new Timer(Execute, null, Timeout.Infinite, 0);

  • }


  • public void Execute(object state = null)

  • {

  • try

  • {

  • Logger.LogInformation("Begin execute service");

  • ExecuteAsync().Wait();

  • }

  • catch (Exception ex)

  • {

  • Logger.LogError(ex, "Execute exception");

  • }

  • finally

  • {

  • Logger.LogInformation("Execute finished");

  • }

  • }


  • protected abstract Task ExecuteAsync();


  • public virtual void Dispose()

  • {

  • _timer?.Dispose();

  • }


  • public Task StartAsync(CancellationToken cancellationToken)

  • {

  • Logger.LogInformation("Service is starting.");

  • _timer.Change(TimeSpan.FromSeconds(SecurityHelper.Random.Next(10)), _period);

  • return Task.CompletedTask;

  • }


  • public Task StopAsync(CancellationToken cancellationToken)

  • {

  • Logger.LogInformation("Service is stopping.");


  • _timer?.Change(Timeout.Infinite, 0);


  • return Task.CompletedTask;

  • }

  • }

  • 基于上面這個基于Timer實現的后臺定時任務類實現一個定時任務:

  • public class RemoveOverduedReservtaionService : ScheduedService

  • {

  • public RemoveOverduedReservtaionService(ILogger<RemoveOverduedReservtaionService> logger) : base(TimeSpan.FromDays(1), logger)

  • { }


  • protected override Task ExecuteAsync()

  • {

  • return DependencyResolver.Current.TryInvokeServiceAsync<IEFRepository<ReservationDbContext, Reservation>>(reservationRepo =>

  • {

  • return reservationRepo.DeleteAsync(reservation => reservation.ReservationStatus == 0 && (reservation.ReservationForDate < DateTime.Today.AddDays(-3)));

  • });

  • }

  • }

  • 這個類實現的是每天執行一次,刪除三天前狀態為待審核的預約,完整實現代碼:https://github.com/WeihanLi/ActivityReservation/blob/dev/ActivityReservation.Helper/Services/RemoveOverduedReservtaionService.cs

    執行日志:

    通過日志可以看到我們的定時任務確實是每天執行一次,這樣我們的定時任務就算是簡單的完成了。

    Reference

    • https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services

    • https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/multi-container-microservice-net-applications/background-tasks-with-ihostedservice

    • https://docs.microsoft.com/zh-cn/dotnet/standard/microservices-architecture/multi-container-microservice-net-applications/background-tasks-with-ihostedservice

    • https://www.stevejgordon.co.uk/asp-net-core-2-ihostedservice

    • https://github.com/WeihanLi/ActivityReservation


    總結

    以上是生活随笔為你收集整理的.net core 基于 IHostedService 实现定时任务的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。