dotnet/runtime

Console.GetCursorPosition behaves oddly with multiple threads on WSL

Open

#109.440 aperta il 1 nov 2024

Vedi su GitHub
 (2 commenti) (0 reazioni) (0 assegnatari)C# (5445 fork)batch import
area-System.Consolehelp wanted

Metriche repository

Star
 (17.886 star)
Metriche merge PR
 (Merge medio 12g 11h) (661 PR mergiate in 30 g)

Descrizione

Description

Reproduction Steps

  • Create a new console project, targeting .NET 8 or .NET 9.
  • Run the following:
static void Main(string[] args)
{
    Task.Run(() =>
    {
        while (true)
        {
            Console.WriteLine($"CursorPosition = {Console.GetCursorPosition()}");
            Thread.Sleep(1000);
        }
    });

    for (int i = 0; i < 10; i++)
    {
        string? input = Console.ReadLine();

        if (i == 2)
        {
            Console.GetCursorPosition();
            Console.GetCursorPosition();
        }
    }
}

Expected behavior

"CursorPosition = ..." should be printed every second, or remain blocked until the calls to Console.ReadLine() complete.

Actual behavior

In each iteration of the loop, nothing is printed until a string is read from Console.ReadLine(). However, once Console.GetCursorPosition() is called twice in the same iteration of the loop, the "CursorPosition = ..." line is printed every second as expected.

For example, CursorPosition = ... is only outputted after a new line is inputted, but after the GetCursorPosition lines are executed, the output continues without anything having been entered:

the
CursorPosition = (0, 2)
quick
CursorPosition = (0, 4)
brown
CursorPosition = (0, 6)
CursorPosition = (0, 7)
CursorPosition = (0, 8)
CursorPosition = (0, 9)

Moving one of the GetCursorPosition calls before the Console.ReadLine produces the same result as when both calls are done after the Console.ReadLine:

for (int i = 0; i < 10; i++)
{
    Console.GetCursorPosition();
    string? input = Console.ReadLine();
    if (i == 2)
        Console.GetCursorPosition();
}

Note the i == 2 can be any number (and the loop max is irrelevant), this is only to show behavior is consistent before GetCursorPosition is called a second time.

Regression?

No response

Known Workarounds

No response

Configuration

  • Occurs in both .NET 8.0.403 and 9.0.100-preview.7.24407.12
  • Running Ubuntu 22.04 via WSL2 on Windows 11.
  • Same behavior in debug and release builds
  • Outside of WSL, the task outputs every second as expected on both .NET versions.

Other information

No response

Guida contributor