Created
October 27, 2016 12:33
-
-
Save Sidneys1/b1c6efb7d5d10843c32b9dcf63753a13 to your computer and use it in GitHub Desktop.
A ReadLine wrapper that allows cancellable and timeoutable Console.ReadLine calls
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal static class InterruptableReadline { | |
private static readonly AutoResetEvent StartReading = new AutoResetEvent(false); | |
private static readonly AutoResetEvent DoneReading = new AutoResetEvent(false); | |
private static readonly Thread ReadThread = new Thread(ReadThreadMain) { IsBackground = true }; | |
private static string _readVal; | |
private static bool _cancelled; | |
static InterruptableReadline() { ReadThread.Start(); } | |
public static void Shutdown() { ReadThread.Abort(); } | |
private static void ReadThreadMain() { | |
while (true) { | |
StartReading.WaitOne(); | |
_readVal = Console.ReadLine(); | |
DoneReading.Set(); | |
} | |
} | |
public static string ReadLine() => ReadLine(new TimeSpan(0, 0, 0, 0, -1)); | |
public static string ReadLine(int milliseconds) => ReadLine(new TimeSpan(0, 0, 0, 0, milliseconds)); | |
public static string ReadLine(TimeSpan timeout) { | |
lock (StartReading) { // Prevent concurrent calls | |
_readVal = null; | |
_cancelled = false; | |
StartReading.Set(); | |
if (!DoneReading.WaitOne(timeout)) | |
throw new TimeoutException("The ReadLine timeout expired."); | |
if (_readVal == null && _cancelled) | |
throw new OperationCanceledException("The ReadLine was cancelled."); | |
return _readVal; | |
} | |
} | |
public static void CancelReadline() { | |
_cancelled = true; | |
DoneReading.Set(); | |
lock (StartReading) { } // Make sure the ReadLine method returns first | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment