C# 要在.NET core中并行运行的多个工作进程

C# 要在.NET core中并行运行的多个工作进程,c#,.net-core,backgroundworker,C#,.net Core,Backgroundworker,我已经在.NET Core中创建了一个工人服务项目,打算让3名独立工人参与。所有这3名工人应平行运行,且独立于其他工人。这个辅助服务作为一个整体将作为Windows服务运行 在main Program.cs中,我注册了以下3名工人: public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseWin

我已经在.NET Core中创建了一个工人服务项目,打算让3名独立工人参与。所有这3名工人应平行运行,且独立于其他工人。这个辅助服务作为一个整体将作为Windows服务运行

在main Program.cs中,我注册了以下3名工人:

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseWindowsService()
                .ConfigureServices((hostContext, services) =>
                {
                    IConfiguration configuration = hostContext.Configuration;
                    services.AddHostedService<WorkerA>();
                    services.AddHostedService<WorkerB>();
                    services.AddHostedService<WorkerC>();
                });
    }
问题陈述:当我执行项目时,我面临的问题很少,例如,当WorkerA没有任何流程运行时,WorkerB或WorkerC不开始工作。我认为这基本上是等待WorkerA在WorkerB或WorkerC开始工作之前做点什么


请告知他们如何独立工作,即:每个工人不应等待其他工人,而应独立运行

遗憾的是,在.NETCore中,您只能初始化1个HostedService,这意味着只有第一个inyected将在后台运行。一个可行的解决方案是创建一个HostedService包装器,它初始化类:

public class Orchestrator: IHostedService
{
    private readonly WorkerA _workerA;
    private readonly WorkerB _workerB;

    public Orchestrator(WorkerA workerA, WorkerB workerB)
    {
        _workerA = workerA;
        _workerB = workerB;
    }
    #endregion

    public Task StartAsync(CancellationToken cancellationToken)
    {
        Task.Run(async () => await _workerA.StartAsync(cancellationToken));
        Task.Run(async () => await _workerB.StartAsync(cancellationToken));

        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.WhenAll(StartAsync(cancellationToken));
    }
}
当我执行项目时,我面临的问题很少,例如,当WorkerA没有任何流程运行时,WorkerB或WorkerC不开始工作。我认为这基本上是等待WorkerA在WorkerB或WorkerC开始工作之前做点什么

.NET Core允许任何数量的托管服务;但是,它开始连续执行它们。所以这个代码的问题是:

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
  while (!stoppingToken.IsCancellationRequested)
  {
    WorkerA_DoWork();
    await Task.Delay(6000, stoppingToken);
  }
}
工作是同步的。也就是说,它同步地等待工作完成

解决方案可以是两件事之一。使“获取下一个工作项”方法异步:

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
  while (!stoppingToken.IsCancellationRequested)
  {
    await WorkerA_DoWorkAsync();
    await Task.Delay(6000, stoppingToken);
  }
}
或将整个ExecuteAsync包装在任务中。运行:


如果你的员工的工作彼此不相关,为什么不将他们分为不同的服务?在这个场景中,您还具有更好的服务隔离,如果一个工作人员停止工作,其他工作人员仍在工作。在您的情况下,如果WorkerA引发异常,则整个服务将关闭。感谢您的反馈!我认为你的解决方案是最后的选择。只是想看看是否有一个可用的选项。感谢您的反馈!我会检查你的解决方案,看看是否能满足我的要求。
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
  while (!stoppingToken.IsCancellationRequested)
  {
    await WorkerA_DoWorkAsync();
    await Task.Delay(6000, stoppingToken);
  }
}
protected override Task ExecuteAsync(CancellationToken stoppingToken) => Task.Run(async () =>
{
  while (!stoppingToken.IsCancellationRequested)
  {
    WorkerA_DoWork();
    await Task.Delay(6000, stoppingToken);
  }
});