Tyrrrz / CliFx

Class-first framework for building command-line interfaces
MIT License
1.5k stars 61 forks source link

ConsoleWriter is not thread-safe #123

Closed alirezanet closed 2 years ago

alirezanet commented 2 years ago

Version

2.2.1

Details

Long story short the SystemConsole must be thread-safe like the normal Console.

Steps to reproduce

Run the bellow example a few times:

public class TestClass
{
    private IConsole console;
    private Random rnd;
    private int DoneCounter = 0;
    private int ErrorCounter = 0;

    public TestClass()
    {
        console = new SystemConsole();
        rnd = new Random();
    }
    public async Task Run()
    {
        var strings = new List<string>(Enumerable.Repeat(new string('x', 100), 1000));
        var options = new ParallelOptions
        {
            MaxDegreeOfParallelism = 10 
        };
        await Parallel.ForEachAsync(strings, options, async (task, _) => await Execute(task));

        Console.WriteLine($"\nDone: {DoneCounter}\nError: {ErrorCounter}");
    }

     public async Task Execute(string task)
    {
        try
        {
            await Task.Delay(rnd.Next(1, 100));
            console.Output.Write(task);
            Interlocked.Increment(ref DoneCounter);
        }
        catch (Exception ex)
        {
            Interlocked.Increment(ref ErrorCounter);
        }
    }
}

run:

public static partial class Program
{
    public static async Task Main()
    {
        var test = new TestClass();
        await test.Run();
        Console.Read();
    }
}
Tyrrrz commented 2 years ago

Fixed the issue. Thanks for the repro!