如何使用两个 Net6 Worker 服务访问的锁同步共享变量?

How to sync shared variables using Locks accessed by two Net6 Worker services?


IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.AddHostedService<Worker1>();
        services.AddHostedService<Worker2>();
    })
    .Build();

await host.RunAsync();

在VS2022中,在Program.cs里面(以上是它的全部内容),我连全局静态变量(两个Worker共享和更新)都声明不了,怎么办我可以使用 Locks 在两个 Worker 之间同步更新。任何帮助将不胜感激。

根据@AndrewSilver的建议解决,将共享变量放在单独的文件中:

public static class AK_Configs
{
    public static bool notOK = false;
    public static object _lock = new object();
    public static Flags flags = new Flags();   
    public static Random random = new Random();
    public static int countInc = 0;
    public static int countDec = 0;
    public static int countCheck = 0;
}
public class Flags
{
    public int I { get; set; }
    public int J { get; set; }

    public override string ToString()
    {
        return $"I={I},J={J}";
    }
}

节目:

services.AddHostedService<Worker1>();//read/wite Worker
services.AddHostedService<Worker2>();//read/wite Worker
services.AddHostedService<Worker3>();//readonly Worker

Worker1:增加 I 和 J

while (!stoppingToken.IsCancellationRequested)
{
   lock (AK_Configs._lock)
   {
      AK_Configs.countInc++;                    
      Thread.Sleep(AK_Configs.random.Next(10) * 100);
      AK_Configs.flags.I++;                    
      Thread.Sleep(AK_Configs.random.Next(10) * 100);
      AK_Configs.flags.J++;
      _logger.LogInformation($"===Increase {AK_Configs.countInc}:{AK_Configs.flags}");
   }
   await Task.Delay(15, stoppingToken);
 }

Work2: 递减 I 和 J

while (!stoppingToken.IsCancellationRequested)
{
    lock (AK_Configs._lock)
    {
       AK_Configs.countDec++;
                                
       Thread.Sleep(AK_Configs.random.Next(10)*100);
       AK_Configs.flags.I--;
                
        Thread.Sleep(AK_Configs.random.Next(10)*100);
        AK_Configs.flags.J--;
        _logger.LogInformation($"---Decrease {AK_Configs.countDec}:{AK_Configs.flags}");
     }
     await Task.Delay(15, stoppingToken);
 }

Worker3:只读,注意数据不一致

    while (!stoppingToken.IsCancellationRequested)
    {
        lock (AK_Configs._lock)
        {
            AK_Configs.countCheck++;
            if (AK_Configs.flags.I != AK_Configs.flags.J)
            {
                _logger.LogInformation("Data corrupted! flags:" + (AK_Configs.flags));
                _appLifetime.StopApplication();
            }
        }
        await Task.Delay(15, stoppingToken);
    }