0

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

await host.RunAsync();

在VS2022中,Program.cs里面(上面是全部内容),我什至不能声明全局静态变量(由两个Worker共享和更新),如何做到这一点,以便我可以使用锁来同步两个工人之间的更新。任何帮助将不胜感激。

4

1 回答 1

0

它是根据@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);
    }
于 2022-02-04T13:59:54.470 回答