2

我有两个后台服务。其中一个通过串行端口执行测量,另一个称为 SettingsWorker 获取测量设置(如传感器数量、模块、获取延迟等)并通过静态变量共享它。

public class MeasurementWorker : BackgroundService
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {

                    ....
                    await Task.Delay(_measurementSettings.MeasurementFetchPeriod, stoppingToken);
                }
             }

public class SettingsWorker : BackgroundService
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {

                    ....
                    await Task.Delay(_measurementSettings.MeasurementFetchPeriod, stoppingToken);
                }
             }

这是我的程序课。

        .ConfigureServices((hostContext, services) =>
        {
            services.AddHostedService<SettingsWorker>();
            services.AddHostedService<MeasurementWorker>();

        }).UseSerilog();

当我的应用程序始终启动时,必须首先执行 SettingWorker 并设置共享静态变量。在我的观察中,排序服务。AddHostedService 在应用程序启动时更改执行顺序。

如果我首先添加 SettingsWorker 是否保证它将首先执行后台任务?

如果在我的情况下有多个后台服务,当任何服务尚未完成执行且尚未到达 await Task.Delay 行时,它是否可能会停止并且另一个后台服务开始运行只是因为已达到延迟时间。

4

1 回答 1

0

我做了一些关于重叠调用的实验。我创建了两个后台服务,如下所示。(BackgroundService2与BackgroundService1相同,除了它记录为BackgroundService 2)

public class BackgroundService1 : BackgroundService
    {
        private int executionCount = 0;
        private readonly ILogger<BackgroundService1> _logger;
        private Timer _timer;

        public BackgroundService1(ILogger<BackgroundService1> logger)
        {
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation($"BackgroundService 1 start to work. Thread ID : {Thread.CurrentThread.ManagedThreadId} Count: {executionCount}");
                executionCount++;
                _logger.LogInformation($"BackgroundService 1 done work. Thread ID : {Thread.CurrentThread.ManagedThreadId} Count: {executionCount}");
                await Task.Delay(100, stoppingToken);
            }
        }

这是重叠调用的快照。 在此处输入图像描述

如果我们不想调用后台服务,除非之前的调用已经完成,我们必须通过静态共享变量来控制它,比如;

if (!numberOfActiveJobs==1) {
Interlocked.Increment(numberOfActiveJobs);

虽然我没有找到关于应用程序启动时哪个后台服务首先工作的文档,但它似乎取决于后台服务的注册顺序。注意(我还观察到启动后台作业的线程完成作业。例如:线程 7 启动作业,(可能被另一个线程中断)线程 7 完成作业

于 2019-12-22T19:53:47.513 回答