ASP.NET Core 上长时间运行后台任务的正确方法,针对 CPU 限制和 I/O 限制

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

在我的 .NET7 ASP.NET 服务器中,我使用此代码在应用程序的生命周期内进行一些后台处理。

_ = Task.Run(async () =>
{
    while (true)
    {
        try
        { 
            if (isDataAvalibale) await DoDBBoundProcessing();
            await Task.Delay(10);
        }
        catch (Exception ex)
        {
            Log.Write("", $"Background error: {ex.Message}");
        }
    }
 }

然后我还有另一个用于 CPUBoundProcessing 的。处理功能必须连续重复。

第一个将数据从 ConcurrentQueue 序列化到数据库,另一个对内存对象进行一些处理。

Task.Run 可以工作,从来没有任何问题,但我知道这不是处理后台处理的最佳方法。
我读过大卫·福勒的这篇文章:
https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md#avoid-using-taskrun-for-long-running-work-that-blocks-the-thread

建议使用:

    var thread = new Thread(ProcessQueue) 
    {
        // This is important as it allows the process to exit while this thread is running
        IsBackground = true
    };
    thread.Start();

Task.Factory.StartNew(ProcessQueue, TaskCreationOptions.LongRunning);

但我不明白哪一个更适合我的用例。 然后是“带有托管服务的后台任务”选项。

我想让事情尽可能简单,就可靠性而言,我当前的 Task.Run 还可以:

  • 服务器停止后台进程就可以了
  • 如果由于某种原因某个处理创建异常并重新启动,也没关系

我只想正确管理线程/任务资源。

我的用例的正确方法是什么?
CPU 绑定和 I/O 绑定操作应该有所不同吗?

谢谢

.net async-await background task-parallel-library threadpool
1个回答
0
投票

您不需要同时使用这两种方法,因为线程池线程将执行您的代码,直到等待任务。延迟代码将返回到池中。10 毫秒后,线程池中的另一个线程将继续执行它离开的位置。 但是您应该处理 asp.net 重新启动事件,因此使用 托管服务 将您的代码(启动您的任务。但不返回该任务)放入 StartAsync 中,并检查循环中的取消令牌。

© www.soinside.com 2019 - 2024. All rights reserved.