1111
1212namespace Microsoft . PowerShell . EditorServices . Console
1313{
14+ using Microsoft . PowerShell . EditorServices . Utility ;
1415 using System ;
1516 using System . Management . Automation ;
1617 using System . Management . Automation . Language ;
@@ -21,6 +22,8 @@ internal class ConsoleReadLine
2122 #region Private Fields
2223
2324 private PowerShellContext powerShellContext ;
25+ private AsyncQueue < ConsoleKeyInfo > readKeyQueue = new AsyncQueue < ConsoleKeyInfo > ( ) ;
26+ private CancellationTokenSource readLoopCancellationToken ;
2427
2528 #endregion
2629
@@ -54,6 +57,8 @@ public async Task<string> ReadCommandLine(CancellationToken cancellationToken)
5457
5558 int currentCursorIndex = 0 ;
5659
60+ this . StartReadLoop ( ) ;
61+
5762 while ( ! cancellationToken . IsCancellationRequested )
5863 {
5964 ConsoleKeyInfo ? possibleKeyInfo = await this . ReadKeyAsync ( cancellationToken ) ;
@@ -382,19 +387,41 @@ public Task<SecureString> ReadSecureLine()
382387
383388 #region Private Methods
384389
385- private async Task < ConsoleKeyInfo ? > ReadKeyAsync ( CancellationToken cancellationToken )
390+ private void StartReadLoop ( )
386391 {
387- while ( ! cancellationToken . IsCancellationRequested )
392+ if ( this . readLoopCancellationToken == null )
388393 {
389- if ( Console . KeyAvailable )
390- {
391- return Console . ReadKey ( true ) ;
392- }
394+ this . readLoopCancellationToken = new CancellationTokenSource ( ) ;
393395
394- await Task . Delay ( 50 ) ;
396+ var terminalThreadTask =
397+ Task . Factory . StartNew (
398+ async ( ) =>
399+ {
400+ // Set the thread's name to help with debugging
401+ Thread . CurrentThread . Name = "ConsoleReadLine Thread" ;
402+
403+ while ( ! this . readLoopCancellationToken . IsCancellationRequested )
404+ {
405+ await this . readKeyQueue . EnqueueAsync (
406+ Console . ReadKey ( true ) ) ;
407+ }
408+ } ,
409+ CancellationToken . None ,
410+ TaskCreationOptions . LongRunning ,
411+ TaskScheduler . Default ) ;
395412 }
413+ }
396414
397- return null ;
415+ private async Task < ConsoleKeyInfo ? > ReadKeyAsync ( CancellationToken cancellationToken )
416+ {
417+ try
418+ {
419+ return await this . readKeyQueue . DequeueAsync ( cancellationToken ) ;
420+ }
421+ catch ( TaskCanceledException )
422+ {
423+ return null ;
424+ }
398425 }
399426
400427 private int CalculateIndexFromCursor (
0 commit comments