0

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

await host.RunAsync();

In VS2022, inside Program.cs(the above is its whole content), I couldn't even declare the gloabal static variables (to be shared and updated by the two Worker), how to do that so that I can use Locks to sync updates between the two Workers. Any help will be appreciated.

Walker66
  • 103
  • 10
  • You couldn't declare them... where? Why? Can you edit your post to answer those questions? – Noah Feb 02 '22 at 22:35
  • Because of [top level statements](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/top-level-statements), most likely. You cannot add static vars in this case - use regular approach with Program.Main() instead. Or just add another abstraction. – AndrewSilver Feb 03 '22 at 19:11
  • Thanks Anddrew and Noah, yes, it's due to top level statements. Followed your suggestion I put shared global variable (static object) in an static class, everything just worked fine in my testing code. Appreciated! – Walker66 Feb 04 '22 at 12:27
  • Another source on [top level statements](https://www.tabsoverspaces.com/233831-exploring-top-level-statements-in-csharp-9). – Walker66 Feb 04 '22 at 14:18

1 Answers1

0

It's resolved based on @AndrewSilver suggestions, put shared variable in a separate file:

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}";
    }
}

Program:

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

Worker1: increment both I and 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: decrement both I and 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:read only and watch for data inconsitence

    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);
    }
Walker66
  • 103
  • 10