using System.Diagnostics; // Stopwatch

using static System.Console;

WriteLine("Proszę poczekać na zakończenie pracy przez zadania.");
Stopwatch stoper = Stopwatch.StartNew();

Task a = Task.Factory.StartNew(MetodaA);
Task b = Task.Factory.StartNew(MetodaB);

Task.WaitAll(new Task[] { a, b });

WriteLine();
WriteLine($"Wyniki: {WspolneObiekty.Komunikat}.");
WriteLine($"Upłynęło {stoper.ElapsedMilliseconds:#,##0} milisekund.");


static void MetodaA()
{
   try
   {
      if (Monitor.TryEnter(WspolneObiekty.Koncha, TimeSpan.FromSeconds(15)))
      {
         for (int i = 0; i < 5; i++)
         {
            Thread.Sleep(WspolneObiekty.Losowe.Next(2000));
            WspolneObiekty.Komunikat += "A";
            Write(".");
         }
      }
      else
      {
         WriteLine("Przekroczenie czasu prób wejścia do monitora konchy.");
      }
   }
   finally
   {
      Monitor.Exit(WspolneObiekty.Koncha);
   }
}

static void MetodaB()
{
   try
   {
      if (Monitor.TryEnter(WspolneObiekty.Koncha, TimeSpan.FromSeconds(15)))
      {
         for (int i = 0; i < 5; i++)
         {
            Thread.Sleep(WspolneObiekty.Losowe.Next(2000));
            WspolneObiekty.Komunikat += "B";
            Write(".");
         }
      }
      else
      {
         WriteLine("Przekroczenie czasu prób wejścia do monitora konchy.");
      }
   }
   finally
   {
      Monitor.Exit(WspolneObiekty.Koncha);
   }
}

static class WspolneObiekty
{
   public static Random Losowe = new();
   public static string Komunikat; // wspólny zasób
   public static object Koncha = new();
}

