IRegisteredObject não está funcionando conforme o esperado
Estou trabalhando em um site ASP.NET 4 (não aplicativo da web). Estou tentando usarIRegisteredObject
para permitir que algum código de longa execução seja executado em um encadeamento sem solicitação.
Para o teste, configurei o intervalo de reciclagem do pool de aplicativos do IIS 7.5 para valores baixos, para que ele tente reciclar enquanto o encadeamento em segundo plano estiver em execução.
Códigopublic 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);
}
}
}
}
ProblemaQuando o pool de aplicativos foi reciclado,IRegisteredObject.Stop
foi chamado comimmediate
definido comofalse
. No entanto, o processo parece terminar antes deStop
retornos; a chamada paraHostingEnvironment.UnregisterObject
nunca é alcançado. Esse comportamento parece contrário às seguintes informações que li:
Disparar e esquecer no ASP.NET:
Se ainda houver objetos registrados em execução após 30 segundos, o ASP.NET chamaráIRegisteredObject.Stop(true)
neles.O ASP.NET descarregará o AppDomain após o retorno de todas essas segundas notificações.Executando trabalho assíncrono, ou tarefas, em aplicativos ASP.NET:
Se necessário, você pode segurar a descarga o tempo que quiser, porque não descarregaremos até que o método Stop retorne pela segunda vez.