简体   繁体   English

使用 Hangfire 作为 Windows 服务正常关闭

[英]Graceful shutdown with Hangfire as a Windows service

I have a Hangfire worker set up as a Windows service and I am trying to make sure it shuts down gracefully (ie completes existing work before shutting down).我有一个 Hangfire 工作人员设置为 Windows 服务,我试图确保它正常关闭(即在关闭之前完成现有工作)。 I've looked at existing Stack Overflow questions and the Hangfire documentation and it doesn't seem to have documentation for how to set up Hangfire as a Windows service for .NET 5. Here is my existing code:我查看了现有的 Stack Overflow 问题和 Hangfire 文档,它似乎没有关于如何将 Hangfire 设置为 .NET 5 的 Windows 服务的文档。这是我现有的代码:

Host.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration(builder => builder.AddJsonFile("appsettings.json", optional: false))
    .ConfigureServices((hostContext, services) =>
    {
        // Register services with container

        services.AddHangfire(configuration => configuration
            .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
            .UseSimpleAssemblyNameTypeSerializer()
            .UseRecommendedSerializerSettings()
            .UseSqlServerStorage(hostContext.Configuration.GetConnectionString("Hangfire"), new SqlServerStorageOptions
            {
                CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
                SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
                QueuePollInterval = TimeSpan.Zero,
                UseRecommendedIsolationLevel = true,
                DisableGlobalLocks = true
            }));

        services.AddHangfireServer(config =>
        {
            config.Queues = new[] { "myqueue" };
        });
    })
.UseNLog()
.UseWindowsService();

Recently I had a similar issue regarding the graceful shutdown in Hangfire.最近我遇到了关于 Hangfire 正常关机的类似问题。 The official way to use graceful shutdown is to use Cancellation Token in your queues and workers.使用优雅关闭的官方方法是在队列和工作人员中使用Cancellation Token

If that doesn't work you can either reschedule all your jobs at shutdown on extend shutdown time:如果这不起作用,您可以在关闭时重新安排所有作业以延长关闭时间:

 public void Configure([...], IHostApplicationLifetime applicationLifetime)
 {
     .
     .
     .
     appLifetime.ApplicationStopping.Register(OnShutdownAsync);
 }

    private async void OnShutdownAsync()
    {
        Task task1 = Task.Factory.StartNew(() =>
        {
            var monitoring = JobStorage.Current.GetMonitoringApi();
            Console.WriteLine(monitoring.ProcessingCount());
            for (var i = 0; i < monitoring.ProcessingCount(); i++)
            {
                foreach (var processingJob in monitoring.ProcessingJobs(1000 * i, 1000))
                {
                    BackgroundJob.Requeue(processingJob.Key);
                }
            }
    
            Console.WriteLine(monitoring.ProcessingCount());
        });
    Task task2 = Task.Factory.StartNew(() => Thread.Sleep(TimeSpan.FromSeconds(45)));
    
    Task.WaitAny(task1, task2);
    Console.WriteLine("All threads complete");
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM