Skip to content

Commit e5537d8

Browse files
Work around InvalidOperationException from Console API (#3755)
1 parent c48f77d commit e5537d8

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

PSReadLine/ConsoleLib.cs

+34-2
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,40 @@ public Encoding OutputEncoding
113113
set { try { Console.OutputEncoding = value; } catch { } }
114114
}
115115

116-
public ConsoleKeyInfo ReadKey() => _readKeyMethod.Value(true);
117-
public bool KeyAvailable => Console.KeyAvailable;
116+
private static T _TryIgnoreIOE<T>(Func<T> f)
117+
{
118+
int triesLeft = 10;
119+
while (true)
120+
{
121+
try
122+
{
123+
triesLeft--;
124+
return f();
125+
}
126+
catch (InvalidOperationException)
127+
{
128+
// Ignore it. An IOE could be thrown if the "application does not have a
129+
// console or when console input has been redirected"... but we don't
130+
// expect PSReadLine to be involved in such a situation. So we are
131+
// actually probably running into this Issue (wherein another process
132+
// attached to the same console terminated at just the right/wrong time):
133+
//
134+
// https://github.com/dotnet/runtime/issues/88697
135+
//
136+
// In the event there is some *other* pathological situation
137+
// happening, we have limited the number of times we will
138+
// swallow/retry this exception/operation.
139+
140+
if (triesLeft <= 0)
141+
{
142+
throw;
143+
}
144+
}
145+
}
146+
}
147+
148+
public ConsoleKeyInfo ReadKey() => _TryIgnoreIOE(() => _readKeyMethod.Value(true));
149+
public bool KeyAvailable => _TryIgnoreIOE(() => Console.KeyAvailable);
118150
public void SetWindowPosition(int left, int top) => Console.SetWindowPosition(left, top);
119151
public void SetCursorPosition(int left, int top) => Console.SetCursorPosition(left, top);
120152
public virtual void Write(string value) => Console.Write(value);

0 commit comments

Comments
 (0)