IRegisteredObject 未按预期工作 [英] IRegisteredObject not working as expected

查看:35
本文介绍了IRegisteredObject 未按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 ASP.NET 4 网站(不是 Web 应用程序).我正在尝试使用 IRegisteredObject 来允许一些长时间运行的代码在非请求线程中运行.

I'm working on an ASP.NET 4 web site (not web application). I'm trying to use IRegisteredObject to allow some long-running code to run in a non-request thread.

为了进行测试,我将 IIS 7.5 应用程序池的回收间隔设置为较低的值,以便在后台线程运行时尝试回收.

For testing, I've set the IIS 7.5 application pool's recycle interval to low values so that it will try to recycle while the background thread is running.

public class AspFriendlyBackgroundJob
{
    private readonly object key = new object();
    private readonly Task task;

    public AspFriendlyBackgroundJob(Action work)
    {
        lock (key)
        {
            HostingEnvironment.RegisterObject(new Stopper(this));
            task = Task.Factory.StartNew(work);
        }
    }

    class Stopper : IRegisteredObject
    {
        private readonly AspFriendlyBackgroundJob job;

        public Stopper(AspFriendlyBackgroundJob job)
        {
            this.job = job;
        }

        public void Stop(bool immediate)
        {
            lock (job.key)
            {
                job.task.Wait();
                HostingEnvironment.UnregisterObject(this);
            }
        }
    }
}

问题

当应用程序池被回收时,IRegisteredObject.Stop 被调用,immediate 设置为 false.但是,该进程似乎在 Stop 返回之前终止;永远不会到达对 HostingEnvironment.UnregisterObject 的调用.这种行为似乎与我阅读的以下信息相反:

Problem

When the application pool was recycled, IRegisteredObject.Stop was called with immediate set to false. However, the process appears to terminate before Stop returns; the call to HostingEnvironment.UnregisterObject never gets reached. This behaviour seems contrary to the following information I read:

在 ASP.NET 上即发即忘:

  • 如果 30 秒后仍有注册对象在运行,ASP.NET 将对它们调用 IRegisteredObject.Stop(true).
  • ASP.NET 将在所有第二个通知返回后卸载 AppDomain.

在 ASP.NET 应用程序中执行异步工作或任务:

如果需要,您可以根据需要暂停卸载,因为在您的 Stop 方法第二次返回之前我们不会卸载.

If you need to, you can hold up the unload as long as you like, because we won’t unload until your Stop method returns the second time.

推荐答案

实际上, IRegisteredObject 按预期工作.我猜您遇到的情况是您的任务可能需要超过关闭时间限制"IIS AppPool 设置中的默认 90 秒.在这种情况下,工作进程将被强行杀死.因此,杀死进程的不是aspnet,而是IIS.修改关机时间限制应该可以解决这个问题,只要注意它不会造成任何问题,因为你会有更多的工作进程实例活着(但旧的只会处理 Stop() 方法,它不会t 处理新请求).

Actually, IRegisteredObject works as expected. What I guess is happening to you is that your task might take more than the default 90 seconds in the "Shutdown Time Limit" IIS AppPool setting. In that case, the worker process will be forcibly killed. So it's not aspnet that's killing the process, but rather IIS. Modifying the Shutdown Time Limit should fix the problem, just take care it doesn't cause any trouble as you'll have more instances of the worker process alive (but the old one will be only processing the Stop() method, it won't handle new requests).

这篇关于IRegisteredObject 未按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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