繁体   English   中英

如何在 .NET Core 3 中实现并行长时间运行的后台任务?

[英]How to implement parallel long running background tasks in .NET Core 3?

我有 .NET 核心控制台应用程序,其中包含两个独立的任务,这些任务应该在应用程序的整个生命周期内并行运行。 我正在考虑使用BackgroundService

class BackgroundTaskOne : BackgroundService
{
    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                // do long running task for the entire life-time of application
                while(true)
                {
                    // do work one
                }
            }
            catch (Exception e)
            {
                // log
            }
        }

        return Task.CompletedTask;
    }
}

class BackgroundTaskTwo : BackgroundService
{
    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                // do long running task for the entire life-time of application
                while(true)
                {
                    // do work two
                }
            }
            catch (Exception e)
            {
                // log
            }
        }

        return Task.CompletedTask;
    }
}

并像这样注册它们:

services.AddHostedService<BackgroundTaskOne>();
services.AddHostedService<BackgroundTaskTwo>();

但这些将按顺序运行。 所以我有两个问题:

  1. 有没有办法让这两个并行运行?
  2. 是否有其他替代方案可以在 .NET Core 中并行运行两个长时间运行的后台进程?

BackgroundService.ExecuteAsync的文档说

实现应该返回一个代表正在执行的长时间运行操作的生命周期的任务。

完成整个工作后,您的实现会返回一个已完成的任务。 事实上,您实现它是为了运行同步而不是异步,这就是不并行运行的原因。

这是一个带有一些虚假异步工作的示例实现:

class BackgroundTaskOne : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                // do work one
                await Task.Delay( 100 );
            }
            catch (Exception e)
            {
                // log
            }
        }
    }
}

如文档所述: https://github.com/dotnet/AspNetCore.Docs/blob/master/aspnetcore/fundamentals/host/hosted-services.md

在 ExecuteAsync 变为异步之前,不会启动其他服务,例如通过调用await

只要您在上面的ExecuteAsync方法中没有提到async子句,我怀疑您的方法整体上是同步的。 这就是为什么两个服务被顺序调用而不是并行调用的原因。 让他们休息一下,引入大量可等待的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM