IRegisteredObject未正常工作 [英] IRegisteredObject not working as expected
问题描述
背景
我工作的一个ASP.NET 4网站(而不是Web应用程序)。我试图用 IRegisteredObject
让一些长期运行code在非请求的线程中运行。
有关测试,我设置了IIS 7.5应用程序池的回收区间低值,这样它会尝试后台线程运行时回收。
code
公共类AspFriendlyBackgroundJob
{
私人只读对象键=新的对象();
私人只读任务的任务; 公共AspFriendlyBackgroundJob(行动工作)
{
锁(钥匙)
{
HostingEnvironment.RegisterObject(新制动器(本));
任务= Task.Factory.StartNew(主持工作);
}
} 班塞:IRegisteredObject
{
私人只读AspFriendlyBackgroundJob工作; 公共塞(AspFriendlyBackgroundJob工作)
{
this.job =工作;
} 公共无效停止(BOOL立即)
{
锁(job.key)
{
job.task.Wait();
HostingEnvironment.UnregisterObject(本);
}
}
}
}
问题
在应用程序池被回收, IRegisteredObject.Stop
调用了立即
设置为假
。然而,过程中出现停止
返回之前终止;调用 HostingEnvironment.UnregisterObject
永远不会被达到。这种行为似乎违背了以下信息我读
- 如果仍有注册30秒后运行的对象,ASP.NET将调用
IRegisteredObject.Stop(真)
在他们身上。
- ASP.NET将卸载AppDomain中所有的第二通知已经返回了。
块引用><一个href=\"http://blogs.msdn.com/b/tmarq/archive/2010/04/14/performing-asynchronous-work-or-tasks-in-asp-net-applications.aspx\"相对=nofollow>执行异步工作或任务,在ASP.NET应用程序的:
如果你需要,你可以只要你喜欢撑起卸载,因为我们不会卸载,直到你停止方法返回的第二次。
块引用>解决方案其实,IRegisteredObject按预期工作。我的猜测是发生在你的是,你的任务可能会超过默认的90秒钟,在关闭时间限制IIS程序池设置。在这种情况下,工作进程将被强制杀死。因此,它不是ASPNET那就是杀死进程,而是非法入境者。修改关闭时间限制应该可以解决问题,只是照顾它不会导致你将有工作进程的多个实例活着任何麻烦(但旧的将只有处理stop()方法,它赢得 T柄新的请求)。
Background
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.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.
Code
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); } } } }
Problem
When the application pool was recycled,
IRegisteredObject.Stop
was called withimmediate
set tofalse
. However, the process appears to terminate beforeStop
returns; the call toHostingEnvironment.UnregisterObject
never gets reached. This behaviour seems contrary to the following information I read:
- If there are still registered objects running after 30 seconds, ASP.NET will call
IRegisteredObject.Stop(true)
on them.- ASP.NET will unload the AppDomain after all those second notifications have returned.
Performing Asynchronous Work, or Tasks, in ASP.NET Applications:
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.
解决方案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屋!