using System.Diagnostics;
internal class Program
{
    private static void Main(string[] args)
    {
        Console.WriteLine("");

        var value = new int[] { 100, 300, 500 };

        foreach (var i in value)
        {
            var a = Create(i, i);
            var b = Create(i, i);

            List<long> times = new() {};

            for (int j = 1; j <= 10; j++)
            {
                var sw = new Stopwatch();
                sw.Start();

                MultiplyCreateTask(a, b, j);

                sw.Stop();
                times.Add(sw.ElapsedMilliseconds);
            }
            Console.WriteLine("Результаты вычисления для количества потоков от 1 до 5 для матрицы cо стороной "+i+": "+string.Join("\t", times));
        }

    }

    private static int[,] Create(int x, int y)
    {
        var rnd = new Random();

        var res = new int[y, x];

        for (int i = 0; i < y; i++)
        {
            for (int j = 0; j < x; j++)
            {
                res[i, j] = rnd.Next(0, 100);
            }
        }
        return res;
    }

    private static int[,] MultiplyCreateTask(int[,] matrix1, int[,] matrix2, int maxCount)
    {
        int[,] res = new int[matrix1.GetLength(0), matrix2.GetLength(1)];

        var semaphore = new SemaphoreSlim(maxCount, maxCount);

        for (int i = 0; i < matrix1.GetLength(0); i++)
        {
            for (int j = 0; j < matrix2.GetLength(1); j++)
            {
                int ci = i;
                int cj = j;

                var task = Task.Run(() =>
                {
                    try
                    {
                       semaphore.Wait();

                       res[ci, cj] = CalculateValue(matrix1, matrix2, ci, cj);
                    }
                    finally
                    {
                        semaphore.Release();
                    }
                });
                
            }
        }
        semaphore.Wait(maxCount);
        return res;
    }

    private static int CalculateValue(int[,] matrix1, int[,] matrix2, int i, int j)
            => Enumerable.Range(0, matrix1.GetLength(1)).Sum(k => matrix1[i, k] * matrix2[k, j]);
}