【问题标题】:ASP.NET Core multithreaded background threadsASP.NET Core 多线程后台线程
【发布时间】:2021-02-09 05:23:59
【问题描述】:

使用 ASP.NET Core .NET 5。在 Windows 上运行。

用户上传需要转换为不同格式的大型工作簿。每个转换过程都是 CPU 密集型的,大约需要一分钟才能完成。

这个想法是使用一种模式,其中请求在后台队列中排队,然后由后台任务处理。

所以,我关注了这个Microsoft article

排队部分运行良好,但问题是工作簿在后台按顺序执行:

private async Task BackgroundProcessing(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCancellationRequested)
    {
        var workItem = 
            await TaskQueue.DequeueAsync(stoppingToken);

        try
        {
            await workItem(stoppingToken);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, 
                "Error occurred executing {WorkItem}.", nameof(workItem));
        }
    }
}

如果我排队 10 个工作簿。在工作簿 1 完成之前,工作簿 2 不会启动。在工作簿 2 完成之前,工作簿 3 不会启动,等等。

因此,我修改了代码以在不等待的情况下运行任务并使用丢弃运算符隐藏警告(请注意 workItem 现在是 Action,而不是 Task):

while (!stoppingToken.IsCancellationRequested)
{
    var workItem = await TaskQueue.DequeueAsync(stoppingToken);

    _ = Task.Factory.StartNew(() =>
        {
            try
            {
                workItem(stoppingToken);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error occurred executing {WorkItem}.", nameof(workItem));
            }
        }, TaskCreationOptions.LongRunning);
}

这行得通——我让所有工作簿大约在同一时间开始处理,然后它们也大约在同一时间完成。但是,我不确定这样做是否危险并且会导致错误、崩溃等。

第二个版本是一个可行的解决方案,还是会在未来导致一些灾难?有没有更好的方法在 ASP.NET 的后台线程上实现并行工作负载?

谢谢。

【问题讨论】:

  • 您愿意使用基于云的排队服务吗?对于这种情况,这将有许多优势。
  • 可以,但必须是 Azure。你有推荐吗?谢谢!

标签: asp.net multithreading asp.net-core


【解决方案1】:

与内存队列相比,使用外部队列具有一些优势。特别是,队列消息存储在可靠的外部存储中,具有重试、多个消费者等功能。如果您的应用程序崩溃,队列项将保留并可以再次尝试。

在 Azure 中,您可以使用多种服务,包括 Azure Storage Queues and Service Bus。我喜欢 Service Bus,因为它使用基于推送的行为来避免代码中需要轮询循环。无论哪种方式,您都可以创建一个 IHostedService 实例,该实例将监视队列并在具有可配置并行化的单独线程中处理工作项。

查找在 ASP.NET Core 中使用的示例,例如:

https://damienbod.com/2019/04/23/using-azure-service-bus-queues-with-asp-net-core-services/

【讨论】:

    【解决方案2】:

    这个想法是使用一种模式,其中请求在后台队列中排队,然后由后台任务处理。

    请求外部代码的proper solution 是使用带有单独后端处理器的持久队列。只要应用程序关闭(例如,在滚动升级期间),任何内存解决方案都会失去该工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-12
      • 2011-01-15
      相关资源
      最近更新 更多