dotnet/runtime

Console.GetCursorPosition behaves oddly with multiple threads on WSL

Open

#109,440 建立於 2024年11月1日

在 GitHub 查看
 (2 留言) (0 反應) (0 負責人)C# (5,445 fork)batch import
area-System.Consolehelp wanted

倉庫指標

Star
 (17,886 star)
PR 合併指標
 (平均合併 12天 11小時) (30 天內合併 661 個 PR)

描述

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

貢獻者指南