加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-core – ASP.NET 5中RegisterObject / QueueBackgroundW

发布时间:2020-12-16 04:29:41 所属栏目:asp.Net 来源:网络整理
导读:在“System.Web”ASP.NET中,可以通过RegisterObject / QueueBackgroundWorkItem注册后台工作,以便参与IIS的关闭序列(完成90秒宽限期),但我很难找到完全等效的ASP.NET 5. 查看 Microsoft.AspNet.Hosting.HostingEngine 的源代码,我可以看到它通过IApplication
在“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...");
});

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读