11
11
12
12
namespace Microsoft . PowerShell . EditorServices . Console
13
13
{
14
+ using Microsoft . PowerShell . EditorServices . Utility ;
14
15
using System ;
15
16
using System . Management . Automation ;
16
17
using System . Management . Automation . Language ;
@@ -21,6 +22,8 @@ internal class ConsoleReadLine
21
22
#region Private Fields
22
23
23
24
private PowerShellContext powerShellContext ;
25
+ private AsyncQueue < ConsoleKeyInfo > readKeyQueue = new AsyncQueue < ConsoleKeyInfo > ( ) ;
26
+ private CancellationTokenSource readLoopCancellationToken ;
24
27
25
28
#endregion
26
29
@@ -54,6 +57,8 @@ public async Task<string> ReadCommandLine(CancellationToken cancellationToken)
54
57
55
58
int currentCursorIndex = 0 ;
56
59
60
+ this . StartReadLoop ( ) ;
61
+
57
62
while ( ! cancellationToken . IsCancellationRequested )
58
63
{
59
64
ConsoleKeyInfo ? possibleKeyInfo = await this . ReadKeyAsync ( cancellationToken ) ;
@@ -382,19 +387,41 @@ public Task<SecureString> ReadSecureLine()
382
387
383
388
#region Private Methods
384
389
385
- private async Task < ConsoleKeyInfo ? > ReadKeyAsync ( CancellationToken cancellationToken )
390
+ private void StartReadLoop ( )
386
391
{
387
- while ( ! cancellationToken . IsCancellationRequested )
392
+ if ( this . readLoopCancellationToken == null )
388
393
{
389
- if ( Console . KeyAvailable )
390
- {
391
- return Console . ReadKey ( true ) ;
392
- }
394
+ this . readLoopCancellationToken = new CancellationTokenSource ( ) ;
393
395
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 ) ;
395
412
}
413
+ }
396
414
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
+ }
398
425
}
399
426
400
427
private int CalculateIndexFromCursor (
0 commit comments