Asp.net core ASP.NET 5中RegisterObject/QueueBackgroundWorkItem的等效项是什么
在“System.Web”ASP.NET中,可以通过Asp.net core ASP.NET 5中RegisterObject/QueueBackgroundWorkItem的等效项是什么,asp.net-core,Asp.net Core,在“System.Web”ASP.NET中,可以通过RegisterObject/QueueBackgroundWorkItem注册后台工作,以参与IIS的关闭顺序(完成90秒的宽限期),但我很难在ASP.NET 5中找到确切的等效项 查看的源代码,我可以看到它通过iaapplicationlifecycle.ApplicationStopping和iaapplicationlifecycle.ApplicationStopping(在这两者之间,它处理服务器和PipelineInstance)
RegisterObject
/QueueBackgroundWorkItem
注册后台工作,以参与IIS的关闭顺序(完成90秒的宽限期),但我很难在ASP.NET 5中找到确切的等效项
查看的源代码,我可以看到它通过iaapplicationlifecycle.ApplicationStopping
和iaapplicationlifecycle.ApplicationStopping
(在这两者之间,它处理服务器和PipelineInstance
)发出信号,但是在旧的API中,似乎没有任何空间可以容纳90秒的宽限期,这就需要RegisterObject
IIS集成层还没有开源(如果有的话),因此很难看到该实现是如何映射的
我是否缺少API?我是否应该通过CancellationToken.Register()执行阻塞关机?这是“vNext的v1”中遗漏的内容吗
任何启示都将不胜感激。我以基于武士刀的Hangfire实现为灵感,创作了以下内容。除了检查IIS Express终止时是否运行关闭代码外,它没有其他测试,但它可以作为概念证明
这里的设计显然不适用于“开火并忘记”任务,因为它们可能在关机之前被触发。但是,它确实适用于幂等队列处理器(假设已禁用空闲关机超时)
我仍然希望得到ASP.NET团队的反馈,但我刚刚注意到,Hangfire通过CancellationToken.Register()
(尽管它的目标是检测关机的Katana等价物)选择阻塞关机(带超时)。
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...");
});