什么等效于ASP.NET 5中的RegisterObject/QueueBackgroundWorkItem [英] What is the equivalent of RegisterObject/QueueBackgroundWorkItem in ASP.NET 5

查看:67
本文介绍了什么等效于ASP.NET 5中的RegisterObject/QueueBackgroundWorkItem的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在"System.Web" ASP.NET中,可以通过RegisterObject/QueueBackgroundWorkItem注册后台工作,以便参与IIS的关闭顺序(完成90秒宽限期),但是努力在ASP.NET 5中找到确切的等效项.

In "System.Web" ASP.NET, background work can be registered via RegisterObject/QueueBackgroundWorkItem in order to take part on the shutdown sequence of IIS (complete with 90 second grace period), but I'm struggling to find the exact equivalent in ASP.NET 5.

查看 Microsoft.AspNet.Hosting.HostingEngine ,我可以看到它通过IApplicationLifecycle.ApplicationStoppingIApplicationLifecycle.ApplicationStopped(在其之间放置服务器和PipelineInstance)发出信号,但是90秒宽限期似乎没有任何余地,因此必须RegisterObject在旧的API中.

Looking at the source for Microsoft.AspNet.Hosting.HostingEngine, I can see that it signals via IApplicationLifecycle.ApplicationStopping and IApplicationLifecycle.ApplicationStopped (between which it disposes the server and PipelineInstance), but there doesn't appear to be any room for the 90 second grace period that necessitates RegisterObject in the old API.

IIS集成层尚未开源(如果有的话),因此很难看到该实现如何映射事物.

The IIS integration layer hasn't been open sourced yet (if ever), so it's difficult to see how that implementation maps things.

我是否缺少API?我应该通过CancellationToken.Register()执行阻止关闭吗?那是"vNext的v1"中遗漏的东西吗?

Am I missing an API? Should I be performing a blocking shutdown via CancellationToken.Register()? Is that something that has been left out of "v1 of vNext"?

任何启蒙将不胜感激.

推荐答案

我使用基于Katana的Hangfire实现作为灵感创建了以下内容.除了检查终止IIS Express时是否运行关闭代码外,它没有任何测试,但是它可以作为概念证明.

I've created the below using the Katana-based Hangfire implementation as inspiration. It has no testing beyond checking that the shutdown code ran when IIS Express was terminated, but it works as a proof of concept.

此处的设计显然不是即发即弃"任务的 not 设计,因为它们可以在关机之前立即触发.但是,它确实适用于幂等队列处理器(假定已禁用了空闲关闭超时)

The design here is obviously not for "fire and forget" tasks, since they could be triggered right before a shutdown. It does, however, work for something like an idempotent queue processor (assuming idle shutdown timeouts have been disabled)

public static class BackgroundServiceExtensions
{
    public static void UseBackgroundService(
        this IApplicationBuilder builder, Func<CancellationToken, Task> service)
    {
        var lifetime = (IApplicationLifetime)builder.ApplicationServices
            .GetService(typeof(IApplicationLifetime));

        var stoppingToken = lifetime.ApplicationStopping;
        var stoppedToken = lifetime.ApplicationStopped;

        // This, in particular, would need to be properly thought out, 
        // preferably including an execution context to minimise threadpool use  
        // for async-heavy background services
        Task serviceTask = Task.Run(() => service(stoppingToken));

        stoppedToken.Register(() =>
        {
            try
            {
                // Block (with timeout) to allow graceful shutdown
                if (!serviceTask.Wait(TimeSpan.FromSeconds(30)))
                {
                    // Log: Background service didn't gracefully shutdown. 
                    //      It will be terminated with the host process
                }
            }
            catch(Exception)
            {
                // Ignored
            }
        });
    }
}

然后可以像这样使用:

app.UseBackgroundService(async cancellationToken =>
{
    while (!cancellationToken.IsCancellationRequested)
    {
        System.Diagnostics.Debug.WriteLine("Tick...");

        try
        {
            // Use cancellationToken for anything that is (logically) cancellable
            await Task.Delay(1000, cancellationToken);
        }
        catch(TaskCanceledException)
        { }
    }

    System.Diagnostics.Debug.WriteLine("Cancellation requested, shutting down...");
});

这篇关于什么等效于ASP.NET 5中的RegisterObject/QueueBackgroundWorkItem的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆