asp.net-core – ASP.NET 5中RegisterObject / QueueBackgroundWorkItem的等价物

前端之家收集整理的这篇文章主要介绍了asp.net-core – ASP.NET 5中RegisterObject / QueueBackgroundWorkItem的等价物前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在“System.Web”ASP.NET中,可以通过RegisterObject / QueueBackgroundWorkItem注册后台工作,以便参与IIS的关闭序列(完成90秒宽限期),但我很难找到完全等效的ASP.NET 5.

查看Microsoft.AspNet.Hosting.HostingEngine的源代码,我可以看到它通过IApplicationLifecycle.ApplicationStopping和IApplicationLifecycle.ApplicationStopped发出信号(在它之间它处理服务器和PipelineInstance),但似乎没有任何空间需要90秒的宽限期旧API中的RegisterObject.

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

我错过了一个API吗?我应该通过CancellationToken.Register()执行阻塞关闭吗?这是“vNext”中遗漏的东西吗?

任何启蒙都会受到高度赞赏.

解决方法

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

这里的设计显然不适用于“即发即忘”任务,因为它们可以在关机前触发.但它确实适用于幂等队列处理器(假设已禁用空闲关闭超时)

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相关文章