ThreadRunningSleepingSlices

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Diagnostics;

public class Program
{
    public static void Main()
    {
        Console.WriteLine($"Environment.ProcessorCount: {Environment.ProcessorCount}");
        Console.WriteLine($"Environment.OSVersion: {Environment.OSVersion}");
        const int threadsCount = 10;
        TimeSpan testDuration = TimeSpan.FromMilliseconds(200);
        TimeSpan idleThreshold = TimeSpan.FromMilliseconds(0.1);
        Console.WriteLine($"Test threads: {threadsCount}, test duration {testDuration.TotalMilliseconds:#,0} msec, idle threshold {idleThreshold.TotalMilliseconds:#,0.00} msec");
        Result[] results = new Result[threadsCount];
        Thread[] threads = Enumerable.Range(0, threadsCount).Select(i => new Thread(() =>
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            TimeSpan sliceStart = stopwatch.Elapsed;
            TimeSpan previous = sliceStart;
            List<Slice> slices = new();
            int loops = 0;
            while (true)
            {
                TimeSpan current = stopwatch.Elapsed;
                if (current > testDuration) break;
                if (current - previous > idleThreshold)
                {
                    slices.Add(new(previous - sliceStart, current - previous));
                    sliceStart = current;
                }
                previous = current;
                loops++;
            }
            results[i] = new(Thread.CurrentThread.ManagedThreadId, slices.ToArray(), loops);
        })).ToArray();
        Array.ForEach(threads, t => t.Start());
        Array.ForEach(threads, t => t.Join());
        foreach (Result result in results)
        {
            Console.WriteLine();
            Console.WriteLine($"Thread #{result.Id} slices:");
            foreach (var (running, sleeping) in result.Slices)
                Console.WriteLine($"- Running: {running.TotalMilliseconds:#,0.00} msec, Sleeping: {sleeping.TotalMilliseconds:#,0.00} msec");
            Console.WriteLine($"- Running AVG: {TimeSpan.FromMilliseconds(result.Slices.Select(e => e.Running.TotalMilliseconds).Average()).TotalMilliseconds:#,0.00} msec, Sleeping AVG: {TimeSpan.FromMilliseconds(result.Slices.Select(e => e.Sleeping.TotalMilliseconds).Average()).TotalMilliseconds:#,0.00} msec, Loops: {result.Loops:#,0}");
        }
    }

    private record struct Slice(TimeSpan Running, TimeSpan Sleeping);
    private record struct Result(int Id, Slice[] Slices, int Loops);
}
;