gpt4 book ai didi

c# - 如果没有应用程序回收,在 ASP.NET 中使用后台 worker 有好处吗?

转载 作者:行者123 更新时间:2023-12-03 12:45:48 24 4
gpt4 key购买 nike

背景:我有一个简单的 ASP.NET Core 3.1 网站。在极少数情况下(每周三到四次),用户可能会填写一个触发发送电子邮件的表单。

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

我不完全理解为什么这在现代 ASP.NET Core 中是必要的。

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

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

然而,我读过的大多数内容都说应用程序回收是旧 ASP 在内存泄漏很常见时的产物,而在 .Net Core 上并不是这样。此外,许多 ASP 应用程序甚至不再托管在 IIS 中。

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

所以:

  • 在 ASP.NET Core 中调用“即发即弃”异步方法是否仍然被认为是不良做法,尤其是当“即发即弃”任务是短暂的时?如果是这样,为什么? [请参阅下面的编辑说明]
  • 除了关闭通知之外,还有什么理由可以认为后台服务比借用托管线程池线程(通过 Task.Run 或 QueueBackgroundWorkItem)更好?唤醒后台服务(如果它正在等待将对象放入集合中)不会以相同的方式使用池线程吗?

编辑:我承认启动任务并向用户报告成功,但操作可能会终止,这种做法很糟糕。收到关闭通知并能够完成任务是有好处的。

或许更好的问题是,现代 ASP(在 IIS 或 Kestrel 上)中是否仍然存在旧的循环行为?是否有其他原因可能会触发有序关闭(服务器关闭/手动停止除外)?

最佳答案

我仍然认为这是一种糟糕的做法。

此处以及引用帖子中的主要关注点主要是关于任务完成的 promise 。

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

使用 fire forget task 通常意味着,当进程重新启动时,您的任务有可能不得不重新开始。有时由于上下文丢失,这是不可能的。想象一下,您的 fire-forget 任务正在使用 Web 请求提供的参数调用另一个 Web API。如果进程重新启动,这些参数可能会从内存中删除。

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

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

就生命周期而言 - 托管服务是您注册到 DI 的类型,因此可以使用 DI 功能,例如 this built-in hosted service实现了 IDisposable,这意味着可以在关闭时进行适当的清理。

坦率地说,后台任务和托管服务都可以让您“即发即弃”。但是,当您需要可靠性和弹性时,托管服务会胜出。

关于c# - 如果没有应用程序回收,在 ASP.NET 中使用后台 worker 有好处吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61050091/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com