示例#1
0
        public async Task <ConsoleKeyInfo> ReadKeyAsync(CancellationToken cancellationToken)
        {
            await s_readKeyHandle.WaitAsync(cancellationToken);

            // I tried to replace this library with a call to `stty -echo`, but unfortunately
            // the library also sets up allowing backspace to trigger `Console.KeyAvailable`.
            InputEcho.Disable();
            try
            {
                while (!await WaitForKeyAvailableAsync(cancellationToken))
                {
                    ;
                }
            }
            finally
            {
                InputEcho.Enable();
                s_readKeyHandle.Release();
            }

            await s_stdInHandle.WaitAsync(cancellationToken);

            try
            {
                return(System.Console.ReadKey(intercept: true));
            }
            finally
            {
                s_stdInHandle.Release();
            }
        }
示例#2
0
 private static async Task WaitForKeyAvailableAsync(CancellationToken cancellationToken)
 {
     InputEcho.Disable();
     try
     {
         while (!Console.KeyAvailable)
         {
             await Task.Delay(50, cancellationToken);
         }
     }
     finally
     {
         InputEcho.Enable();
     }
 }
        public ConsoleKeyInfo ReadKey(bool intercept, CancellationToken cancellationToken)
        {
            s_readKeyHandle.Wait(cancellationToken);

            // On Unix platforms System.Console.ReadKey has an internal lock on stdin.  Because
            // of this, if a ReadKey call is pending in one thread and in another thread
            // Console.CursorLeft is called, both threads block until a key is pressed.

            // To work around this we wait for a key to be pressed before actually calling Console.ReadKey.
            // However, any pressed keys during this time will be echoed to the console. To get around
            // this we use the UnixConsoleEcho package to disable echo prior to waiting.
            if (Utils.IsPS6)
            {
                InputEcho.Disable();
            }

            try
            {
                // The WaitForKeyAvailable delegate switches between a long delay between waits and
                // a short timeout depending on how recently a key has been pressed. This allows us
                // to let the CPU enter low power mode without compromising responsiveness.
                while (!WaitForKeyAvailable(cancellationToken))
                {
                    ;
                }
            }
            finally
            {
                if (Utils.IsPS6)
                {
                    InputEcho.Disable();
                }
                s_readKeyHandle.Release();
            }

            // A key has been pressed, so aquire a lock on our internal stdin handle. This is done
            // so any of our calls to cursor position API's do not release ReadKey.
            s_stdInHandle.Wait(cancellationToken);
            try
            {
                return(System.Console.ReadKey(intercept));
            }
            finally
            {
                s_stdInHandle.Release();
            }
        }