Skip to content

Commit d07fd5b

Browse files
committed
Fix ReadKeyAsync on Linux
1 parent 20ada00 commit d07fd5b

File tree

1 file changed

+35
-8
lines changed

1 file changed

+35
-8
lines changed

src/PowerShellEditorServices/Console/ConsoleReadLine.cs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace 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

Comments
 (0)