Skip to content

Proposal: Async Console I/O APIs #299

Open

Description

@hez2010

Proposal

Async Console I/O APIs

Since now we can write async Task Main, I think it's necessary to add APIs to support cancellable async console I/O operations without needs of operating Console.In, Console.Out directly for converience.

Proposed APIs

public static class Console 
{
+    public static Task WriteAsync(string content, CancellationToken cancellationToken);
+    // ... other overloads for char, int and etc
+    public static Task WriteLineAsync(T content, CancellationToken cancellationToken);
+    // ... other overloads for char, int and etc
+    public static Task<int> ReadKeyAsync(CancellationToken cancellationToken);
+    public static Task<string> ReadLineAsync(CancellationToken cancellationToken);
}

Activity

  1. huoyaoyuan commented on Nov 26, 2019

    @huoyaoyuan
    Member

    There are so many overloads on textwriter. Accessing In or Out is just literally 3 or 4 characters without any code flow changes, and can be much shorter if saved as variable.

    Only ReadKeyAsync is really benificial.

  2. fbrosseau commented on Nov 30, 2019

    @fbrosseau

    Also, at least under Windows, but I would assume other implementations are similar, the in/out streams are implemented as synchronous-only streams, so the proposal to have first-class async methods on Console would be a misleading hidden threadpool block.

  3. added this to the Future milestone on Jun 22, 2020
  4. added
    api-suggestionEarly API idea and discussion, it is NOT ready for implementation
    and removed
    untriagedNew issue has not been triaged by the area owner
    on Jun 22, 2020
  5. adamsitnik commented on Nov 14, 2023

    @adamsitnik
    Member

    Console is not opened for async IO on Windows, but with #87103 and #72503 we should be able to get cancellation support on Windows. I wonder whether it would be possible to implement it on Unix.

    cc @stephentoub @tmds

  6. tmds commented on Nov 16, 2023

    @tmds
    Member
    +    public static Task WriteAsync(string content, CancellationToken cancellationToken);
    +    // ... other overloads for char, int and etc
    +    public static Task WriteLineAsync(T content, CancellationToken cancellationToken);
    

    These don't seem particularly useful: usually you want to block until the output was written.

    +    public static Task<int> ReadKeyAsync(CancellationToken cancellationToken);
    +    public static Task<string> ReadLineAsync(CancellationToken cancellationToken);

    These have a UX race between cancellation and the user providing input: was the input for the previous or the next caller?

    If ReadKeyAsync incercepts (like ReadKey(incercept: true)) on cancellation the key could go back in the queue.

    I wonder whether it would be possible to implement it on Unix.

    I think we may perform the read on a separate thread where it blocks until there is input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions