在应用程序启动时运行IHostedService函数,但只能运行一次



每次应用程序启动时,我都需要run a functiononce(该函数检查我的DB中的特定Mongo collection并插入我自己预定义的文档)。

IHostedService/BackgroundService似乎能够完成这项工作。我只需要把这个服务注入到我的Startup.cs文件中。

然而,我想知道是否有任何方式,我可以优雅地完成这个任务,因为IHostedService实际上是为了实现更多的cron job(一个需要在一段时间间隔内运行的任务,比如每30分钟)。

谢谢。

EDIT: 误解,必须在应用程序启动后执行单个任务。

有多种方法来解决它,但我会选择IHostApplicationLifetime::ApplicationStarted。您可以创建一个扩展方法来注册将在启动时执行的函数。

public static class HostExtensions
{
public static void CheckMongoCollectionOnStarted(this IHost host)
{
var scope = host.Services.CreateScope();
var lifetime = scope.ServiceProvider.GetService<IHostApplicationLifetime>();
var loggerFactory = scope.ServiceProvider.GetService<ILoggerFactory>();
var logger = loggerFactory!.CreateLogger("CheckMongoCollectionOnStarted");
lifetime!.ApplicationStarted.Register(
async () =>
{
try
{
logger.LogInformation("CheckMongoCollectionOnStarted started");
//TODO: add your logic here
await Task.Delay(2000); //simulate working
logger.LogInformation("CheckMongoCollectionOnStarted completed");
}
catch (Exception ex)
{
//shutdown if fail?
logger.LogCritical(ex, "An error has occurred while checking the Mongo collection. Shutting down the application...");
lifetime.StopApplication();
}
finally
{
scope.Dispose();
}
}
);
}
}

然后从Program类调用扩展:

public class Program
{
public static async Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
host.CheckMongoCollectionOnStarted();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>());
}

我能够通过使用ihostdservice实现我想要的。

protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
//logic
}

在Startup.cs中,我是这样注册我的服务的

AddSingleton<IHostedService, myService>

我运行我的应用程序,它调试到AddSingleton行,只运行ExecuteAsync函数一次。这就是我的解决方案。

最新更新