Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Threading;
- using System.Threading.Tasks;
- /// <summary>
- /// CancelKey の受付。
- ///
- /// <code><![CDATA[
- /// using (var ck = CancelKey.Create())
- /// {
- /// ck.Token
- /// }
- /// ]]></code>
- /// </summary>
- public static class CancelKey
- {
- /// <summary>
- /// <see cref="Console.CancelKeyPress/> の受付開始。
- /// </summary>
- /// <returns></returns>
- public static CancelKeyRegistration Create() => new CancelKeyRegistration(new CancellationTokenSource());
- /// <summary>
- /// <see cref="Console.CancelKeyPress"/> の購読解除用の disposable。
- /// </summary>
- public struct CancelKeyRegistration : IDisposable
- {
- private CancellationTokenSource _cts;
- private ConsoleCancelEventHandler _handler;
- internal CancelKeyRegistration(CancellationTokenSource cts)
- {
- _cts = cts;
- var handler = cts.ToCancelEventHandler();
- _handler = handler;
- Console.CancelKeyPress += handler;
- }
- /// <summary>
- /// <see cref="Console.CancelKeyPress"/> が発生したときにキャンセルされる<see cref="CancellationToken"/>。
- /// </summary>
- public CancellationToken Token => _cts.Token;
- public void Dispose()
- {
- // Ctrl + C された後にここを通るとデッドロックしてる感じある。
- Console.CancelKeyPress -= _handler;
- _cts.Dispose();
- }
- }
- /// <summary>
- /// <see cref="CancellationTokenSource.Cancel"/>を<see cref="ConsoleCancelEventHandler"/>でラップする。
- /// </summary>
- /// <param name="cts"></param>
- /// <returns></returns>
- private static ConsoleCancelEventHandler ToCancelEventHandler(this CancellationTokenSource cts) => cts.Cancel;
- private static void Cancel(this CancellationTokenSource cts, object sender, ConsoleCancelEventArgs e) => cts.Cancel();
- }
- class Program
- {
- static async Task Main()
- {
- using (var ck = CancelKey.Create())
- {
- ck.Token.Register(() => Console.WriteLine("cancelled"));
- while (!ck.Token.IsCancellationRequested)
- {
- Console.WriteLine(".");
- await Task.Delay(100, ck.Token);
- }
- Console.WriteLine("a");
- }
- }
- }
Add Comment
Please, Sign In to add comment