Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Runtime.InteropServices;
- using System.Threading;
- using System.Threading.Tasks;
- namespace System
- {
- public static class AsyncConsole
- {
- /// <see href="https://docs.microsoft.com/en-us/windows/console/getstdhandle"/>
- private enum StdHandle
- {
- STD_INPUT_HANDLE = -10,
- STD_OUTPUT_HANDLE = -11,
- STD_ERROR_HANDLE = -12
- }
- /// <see href="https://docs.microsoft.com/en-us/windows/console/getstdhandle"/>
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern IntPtr GetStdHandle(int nStdHandle);
- /// <see href="https://docs.microsoft.com/en-us/windows/desktop/FileIO/cancelioex-func"/>
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern bool CancelIoEx(IntPtr handle, IntPtr lpOverlapped);
- public static async Task<ConsoleKeyInfo> ReadKey(CancellationToken cancellationToken = default)
- {
- cancellationToken.ThrowIfCancellationRequested();
- using (RegisterReadCancel(cancellationToken))
- {
- return await Task.Run(() =>
- {
- try
- {
- return Console.ReadKey();
- }
- catch (InvalidOperationException inner)
- {
- throw new OperationCanceledException("Operation cancelled.", inner, cancellationToken);
- }
- }, cancellationToken);
- }
- }
- public static async Task<ConsoleKeyInfo> ReadKey(bool intercept, CancellationToken cancellationToken = default)
- {
- cancellationToken.ThrowIfCancellationRequested();
- using (RegisterReadCancel(cancellationToken))
- {
- return await Task.Run(() =>
- {
- try
- {
- return Console.ReadKey(intercept);
- }
- catch (InvalidOperationException inner)
- {
- throw new OperationCanceledException("Operation cancelled.", inner, cancellationToken);
- }
- }, cancellationToken);
- }
- }
- public static async Task<string> ReadLine(CancellationToken cancellationToken = default)
- {
- cancellationToken.ThrowIfCancellationRequested();
- using (RegisterReadCancel(cancellationToken))
- {
- return await Task.Run(() =>
- {
- try
- {
- return Console.ReadLine();
- }
- catch (InvalidOperationException inner)
- {
- throw new OperationCanceledException("Operation cancelled.", inner, cancellationToken);
- }
- }, cancellationToken);
- }
- }
- public static async Task<int> Read(CancellationToken cancellationToken = default)
- {
- cancellationToken.ThrowIfCancellationRequested();
- using (RegisterReadCancel(cancellationToken))
- {
- return await Task.Run(() =>
- {
- try
- {
- return Console.Read();
- }
- catch (InvalidOperationException inner)
- {
- throw new OperationCanceledException("Operation cancelled.", inner, cancellationToken);
- }
- }, cancellationToken);
- }
- }
- private static CancellationTokenRegistration RegisterReadCancel(CancellationToken cancellationToken)
- {
- return cancellationToken.Register(() =>
- {
- IntPtr handle = GetStdHandle((int)StdHandle.STD_INPUT_HANDLE);
- CancelIoEx(handle, IntPtr.Zero);
- });
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement