多个工作者在.NET核心中并行运行

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

我已经在.NET Core中创建了一个工人服务项目,其目的是让3位独立工人参与。所有这三名工人应并行运行,并且独立于其他工人。整个工作服务将作为Windows服务运行。

在主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>();
                });
    }

每个工作人员代码如下,完成其预期的工作:

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
     while (!stoppingToken.IsCancellationRequested)
     {
          WorkerA_DoWork();
          await Task.Delay(6000, stoppingToken);
     }
}

问题陈述:当我执行项目时,遇到的问题很少,例如,当WorkerA()没有任何进程要运行时,WorkerB()(或)WorkerC()不会开始工作。我认为基本上是在等待WorkerA()做一些事情之后,WorkerB()或WorkerC()才能开始工作。

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

c# .net-core backgroundworker
2个回答
0
投票

不幸的是,在.net Core中,您只能初始化1 HostedService,这意味着只有第一个被集成的主机会在后台运行。一个可行的解决方案是创建一个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));
    }
}

0
投票

[执行项目时,我遇到的问题很少,例如,当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);
  }
}

WorkerA_DoWork是同步的。也就是说,它正在同步等待工作完成。

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

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
  while (!stoppingToken.IsCancellationRequested)
  {
    await WorkerA_DoWorkAsync();
    await Task.Delay(6000, stoppingToken);
  }
}

或将整个ExecuteAsync包装在Task.Run中:

protected override Task ExecuteAsync(CancellationToken stoppingToken) => Task.Run(async () =>
{
  while (!stoppingToken.IsCancellationRequested)
  {
    WorkerA_DoWork();
    await Task.Delay(6000, stoppingToken);
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.