如果不回收应用程序,在ASP.NET中使用后台工作程序有好处吗?

问题描述 投票:0回答:1

背景:我有一个简单的ASP.NET Core 3.1站点。用户很少(每周三到四次)可能会填写触发电子邮件发送的表格。

我不想在运行“发送电子邮件”操作时延迟页面响应(即使只花一两秒钟),所以从我阅读的所有内容来看,似乎应该处理电子邮件的代码应为background worker/hosted service,并且Razor页面代码应将要发送的数据对象放置在受后台服务监视的集合中。

我尚未完全理解的是为什么在[[现代 ASP.NET Core中这是必需的。

[如果我是在普通的C#应用​​程序(不是ASP)中执行此操作,则只需使“发送电子邮件”方法异步(它使用的是具有异步方法的MailKit),然后不等待就调用异步方法,从而允许在允许响应线程继续的同时,在线程池上完成工作。

但是现有的答案和博客文章说,由于IIS可以重新启动ASP进程(应用程序池回收),因此在ASP is dangerous中无需等待即可调用异步方法。

但是,当内存泄漏很普遍时,我读过的大多数东西都说应用程序回收是旧ASP的产物,而.Net Core上的确不是。此外,许多ASP应用程序甚至都不再托管在IIS中。

据我所知,IHostedService / Background Worker对象没有做任何特别的事情-它们似乎未添加任何其他线程;它们看起来像单例,具有有关环境启动和关闭的其他通知。

所以:

    在ASP.NET Core中调用即发即弃异步方法仍然被认为是不正确的做法,特别是如果即发即弃任务是短暂的?如果是这样,为什么? [请参阅下面的编辑以进行澄清]
  • 除了关闭通知之外,是否有任何理由认为后台服务比借用托管线程池线程(通过Task.Run或QueueBackgroundWorkItem)更好?是否不会以相同的方式唤醒后台服务(如果正在等待将对象放入集合中)将消耗池线程?
  • Edit:我承认在有可能终止操作的情况下,开始执行任务并向用户报告成功的形式不佳。收到关闭通知并能够完成任务是有好处的。

    也许一个更好的问题是,现代ASP(在IIS或Kestrel上)仍然存在自行车的旧行为吗?是否还有其他原因可能触发有序关闭(服务器关闭/手动停止除外)?
  • c# asp.net multithreading asp.net-core .net-core
    1个回答
    1
    投票
    我仍然称其为不良做法。

    这里以及所引用的文章中的主要关注点主要是任务完成的前景。

    [如果不知道幻影后台任务,则运行时将无法通知任务正常停止。这可能会或可能不会导致严重问题,具体取决于终止发生时任务的状态。

    使用失火任务通常意味着,在重新启动过程时,您的任务有重新开始的风险。有时由于上下文丢失,这是不可能的。想象一下,您的“忘记工作”任务正在使用Web请求提供的参数调用另一个Web API。如果进程重新启动,则可能会从内存中清除参数。

    并且请记住,回收并非总是由IIS /服务器触发。它也可能由人触发。假设您的应用程序遇到内存泄漏问题,并且您可能希望每隔1个小时回收一次应用程序进程,以暂时解决问题。然后,您需要确保不中断后台任务。

    在托管方面-仍然可以托管ASP.Net Core应用程序in-process,其中在配置的时间段后(默认为29小时),IIS会回收应用程序池。

    关于生存期

    -托管服务是您注册到DI的类型,因此可以使用DI功能,例如this built-in hosted service实现IDisposable,这意味着可以在关闭时进行适当的清除。 坦白说,后台任务和托管服务都使您无所事事。但是,当您需要可靠性和弹性时,托管服务将赢得胜利。
    © www.soinside.com 2019 - 2024. All rights reserved.