Advertisement
jille_Jr

[C#] Async console reading

Dec 28th, 2018
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.05 KB | None | 0 0
  1. using System.Runtime.InteropServices;
  2. using System.Threading;
  3. using System.Threading.Tasks;
  4.  
  5. namespace System
  6. {
  7.     public static class AsyncConsole
  8.     {
  9.         /// <see href="https://docs.microsoft.com/en-us/windows/console/getstdhandle"/>
  10.         private enum StdHandle
  11.         {        
  12.             STD_INPUT_HANDLE = -10,
  13.             STD_OUTPUT_HANDLE = -11,
  14.             STD_ERROR_HANDLE = -12
  15.         }
  16.  
  17.         /// <see href="https://docs.microsoft.com/en-us/windows/console/getstdhandle"/>
  18.         [DllImport("kernel32.dll", SetLastError = true)]
  19.         private static extern IntPtr GetStdHandle(int nStdHandle);
  20.  
  21.         /// <see href="https://docs.microsoft.com/en-us/windows/desktop/FileIO/cancelioex-func"/>
  22.         [DllImport("kernel32.dll", SetLastError = true)]
  23.         private static extern bool CancelIoEx(IntPtr handle, IntPtr lpOverlapped);
  24.  
  25.         public static async Task<ConsoleKeyInfo> ReadKey(CancellationToken cancellationToken = default)
  26.         {
  27.             cancellationToken.ThrowIfCancellationRequested();
  28.             using (RegisterReadCancel(cancellationToken))
  29.             {
  30.                 return await Task.Run(() =>
  31.                 {
  32.                     try
  33.                     {
  34.                         return Console.ReadKey();
  35.                     }
  36.                     catch (InvalidOperationException inner)
  37.                     {
  38.                         throw new OperationCanceledException("Operation cancelled.", inner, cancellationToken);
  39.                     }
  40.                 }, cancellationToken);
  41.             }
  42.         }
  43.  
  44.         public static async Task<ConsoleKeyInfo> ReadKey(bool intercept, CancellationToken cancellationToken = default)
  45.         {
  46.             cancellationToken.ThrowIfCancellationRequested();
  47.             using (RegisterReadCancel(cancellationToken))
  48.             {
  49.                 return await Task.Run(() =>
  50.                 {
  51.                     try
  52.                     {
  53.                         return Console.ReadKey(intercept);
  54.                     }
  55.                     catch (InvalidOperationException inner)
  56.                     {
  57.                         throw new OperationCanceledException("Operation cancelled.", inner, cancellationToken);
  58.                     }
  59.                 }, cancellationToken);
  60.             }
  61.         }
  62.  
  63.         public static async Task<string> ReadLine(CancellationToken cancellationToken = default)
  64.         {
  65.             cancellationToken.ThrowIfCancellationRequested();
  66.             using (RegisterReadCancel(cancellationToken))
  67.             {
  68.                 return await Task.Run(() =>
  69.                 {
  70.                     try
  71.                     {
  72.                         return Console.ReadLine();
  73.                     }
  74.                     catch (InvalidOperationException inner)
  75.                     {
  76.                         throw new OperationCanceledException("Operation cancelled.", inner, cancellationToken);
  77.                     }
  78.                 }, cancellationToken);
  79.             }
  80.         }
  81.  
  82.         public static async Task<int> Read(CancellationToken cancellationToken = default)
  83.         {
  84.             cancellationToken.ThrowIfCancellationRequested();
  85.             using (RegisterReadCancel(cancellationToken))
  86.             {
  87.                 return await Task.Run(() =>
  88.                 {
  89.                     try
  90.                     {
  91.                         return Console.Read();
  92.                     }
  93.                     catch (InvalidOperationException inner)
  94.                     {
  95.                         throw new OperationCanceledException("Operation cancelled.", inner, cancellationToken);
  96.                     }
  97.                 }, cancellationToken);
  98.             }
  99.         }
  100.  
  101.         private static CancellationTokenRegistration RegisterReadCancel(CancellationToken cancellationToken)
  102.         {
  103.             return cancellationToken.Register(() =>
  104.             {
  105.                 IntPtr handle = GetStdHandle((int)StdHandle.STD_INPUT_HANDLE);
  106.                 CancelIoEx(handle, IntPtr.Zero);
  107.             });
  108.         }
  109.     }
  110. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement