如何使用两个 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);
}
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);
}