【问题标题】:Long-running task without IHostedService running the entire life of the application?没有 IHostedService 运行应用程序的整个生命周期的长时间运行的任务?
【发布时间】:2023-01-21 09:34:32
【问题描述】:

我有一个网站页面,需要选择执行可能需要几分钟的操作。为避免性能问题和超时,我想在 HTTP 请求之外运行此操作。

经过一番研究,我找到了IHostedService和BackgroundService,可以使用AddHostedService<T>()注册为单例。

但我担心的是托管服务始终在运行。当我只希望它按需运行时,这不是浪费资源吗?

有谁知道运行冗长任务的更好选择,或者使用不需要无休止运行的IHostedService的方法?

请注意,该操作调用并等待 API 调用。因此我无法报告操作的进度,也无法在公共数据库中设置标志以判断操作是否已完成。

【问题讨论】:

  • 任务完成后,您可以从服务中停止托管服务。所以基本上它只在计算你的任务时运行。
  • 如果使用 Quartz.NET 来安排作业,它的调度程序不会消耗 CPU 等待作业被触发。添加 Quartz.NET 作为托管服务是easy。
  • @madreflection:谢谢。我不确定使用调度程序是否有意义,因为我希望任务立即运行。你知道 Quartz.NET 是否要求作业是一个单独的应用程序吗?或者它可以触发我的 Web 应用程序中的任务吗?
  • 您可以将其完全包含在您的 ASP.NET Core 应用程序中。
  • @Hille:你是怎么做到的?另外,我将如何重新启动它?

标签: c# .net .net-core razor-pages ihostedservice


【解决方案1】:

按需运行冗长任务同时避免性能问题和超时的一种选择是使用message queue.您可以让您的 Razor Pages 网站在请求操作时向队列发送一条消息,并有一个单独的服务,例如后台工作者,使用队列中的消息并执行操作。这允许您将任务与 Web 请求分离,还允许添加更多工作实例来处理工作负载。

另一种选择是使用task scheduler按需运行,例如Hangfire.它允许您安排后台作业并监视它们的进度,这在您无法报告操作进度的情况下非常有用。

您也可以使用IHostedService, 但你需要确保该服务仅在需要时运行。您可以使用 flag 或 semaphore 来控制服务是否正在运行。您可以在请求操作时设置标志或信号量,并在操作完成时将其清除。然后服务可以在其主循环中检查标志或信号量,如果未设置标志则退出。

总之:

message queue、task scheduler和IHostedService以及控制flag/semaphore都是按需运行冗长任务的可行选项。最佳选择取决于您的具体用例和要求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多