Ser*_*rge 4 background-process .net-core asp.net-core-hosted-services .net-5 ihostedservice
我有一个应用程序,通常应该是一个简单的控制台应用程序,可以编程为 Windows 任务计划程序不时调用的计划任务。
\n该程序应该在两个数据库上启动一些更新,每个数据库一项服务。说ContosoDatabase
应该更新ContosoService
。
最后,它被编写为一个 .NET Core 应用程序,使用s作为服务的基础,这也许不是最好的选择,如下所示:IHostedService
public class ContosoService : IHostedService {\n private readonly ILogger<ContosoService> _log;\n private readonly IContosoRepository _repository;\n \n private Task executingTask;\n\n public ContosoService(\n ILogger<ContosoService> log,\n IContosoRepository repository,\n string mode) {\n _log = log;\n _repository = repository;\n }\n\n public Task StartAsync(CancellationToken cancellationToken) {\n _log.LogInformation(">>> {serviceName} started <<<", nameof(ContosoService));\n executingTask = ExcecuteAsync(cancellationToken);\n\n // If the task is completed then return it, \n // this should bubble cancellation and failure to the caller\n if (executingTask.IsCompleted)\n return executingTask;\n\n // Otherwise it's running\n // >> don't want it to run!\n // >> it should end after all task finished!\n return Task.CompletedTask;\n }\n\n private async Task<bool> ExcecuteAsync(CancellationToken cancellationToken) {\n var myUsers = _repository.GetMyUsers();\n\n if (myUsers == null || myUsers.Count() == 0) {\n _log.LogWarning("{serviceName} has any entry to process, will stop", this.GetType().Name);\n return false;\n }\n else {\n // on mets \xc3\xa0 jour la liste des employ\xc3\xa9s Agresso obtenue\n await _repository.UpdateUsersAsync(myUsers);\n }\n\n _log.LogInformation(">>> {serviceName} finished its tasks <<<", nameof(ContosoService));\n return true;\n }\n\n public Task StopAsync(CancellationToken cancellationToken) {\n _log.LogInformation(">>> {serviceName} stopped <<<", nameof(ContosoService));\n return Task.CompletedTask;\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n我从 main 中这样称呼它:
\npublic static void Main(string[] args)\n{\n try {\n CreateHostBuilder(args).Build().Run();\n }\n catch (Exception ex) {\n Log.Fatal(ex, ">>> the application could not start <<<");\n }\n}\n\npublic static IHostBuilder CreateHostBuilder(string[] args) =>\n Host\n .CreateDefaultBuilder(args)\n .ConfigureServices((hostContext, services) => {\n var config = hostContext.Configuration;\n \n if (args.Contains("Alonso")) {\n services\n .AddHostedService(provider =>\n new AlonsoService(\n provider.GetService<ILogger<AlonsoService>>(),\n provider.GetService<IAlonsoRepository>()));\n }\n\n // if there also Cedig in the list, they can be run in parallel\n if (args.Contains("Contoso")) {\n services\n .AddHostedService(provider =>\n new ContosoService(\n provider.GetService<ILogger<ContosoService>>(),\n provider.GetService<IContosoRepository>()));\n }\n });\n
Run Code Online (Sandbox Code Playgroud)\n现在的问题肯定是,一旦所有更新完成,应用程序就不会停止。
\n有没有办法快速重写应用程序,使其在第二个服务完成其任务后停止?
\n我试图把它放在Environment.Exit(0);
最后
public static void Main(string[] args) {\n try {\n CreateHostBuilder(filteredArgs.ToArray()).Build().Run(); \n }\n catch (Exception ex) {\n //Log....\n }\n\n Environment.Exit(0); // here\n}\n
Run Code Online (Sandbox Code Playgroud)\n但它似乎没有帮助:所有任务完成后应用程序仍在运行。
\n按照@Maxim的建议,我发现了这个肮脏但有效的解决方法,通过注入IHostApplicationLifetime
和lastService
布尔值:
public ConsosoService(
IHostApplicationLifetime hostApplicationLifetime,
// ...
bool lastService)
{ ... }
public async Task StartAsync(CancellationToken cancellationToken)
{
// do the job
if (_lastService)
_hostApplicationLifetime.StopApplication();
// stops the application and cancel/stops other services as well
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4575 次 |
最近记录: |