/// <summary>
        /// 計算を行う本体。別スレッドで実行させる。
        /// </summary>
        /// <param name="args">ThreadArgs型の引数</param>
        static void ExecuteCalculation(object a)
        {
            ThreadArgs args = (ThreadArgs)a;

            // ここで時間のかかる計算処理を実行する
            //   --- 時間がかかる処理のサンプル ---
            int count;

            for (count = 0; count < 10; count++)
            {
                Console.WriteLine($"--- Thread:{Thread.CurrentThread} is alive. Count = {count} ---");
                Thread.Sleep(1000);
            }

            // 処理結果の代入
            args.Count = count;

            // 完了したことを通知
            args.Evt.Set();
        }
        /// <summary>
        /// これはリスナ実装のサンプル。
        /// --------------------------------------------------------------------
        /// ExecuteCalculation()を別スレッドで実行する。キャンセルが通知されたら
        /// ExecuteCalculationスレッドを速やかに破棄して終了する。
        /// --------------------------------------------------------------------
        /// </summary>
        /// <param name="ctkn">呼び出し元からキャンセルを受け取るためのトークン
        static void Listener(CancellationToken ctkn)
        {
            ManualResetEvent evt  = new ManualResetEvent(false);
            ThreadArgs       args = new ThreadArgs()
            {
                Evt = evt,
            };

            // 計算処理を別スレッドで実行
            Thread th = new Thread(ExecuteCalculation);

            th.Start(args);

            // キャンセルとスレッド完了を並列で待つ
            int finish = WaitHandle.WaitAny(new WaitHandle[] { ctkn.WaitHandle, evt });

            // キャンセルされたかスレッド完了かで処理を分ける
            //  --- finishには発火した方のidxが入る ---
            switch (finish)
            {
            case 0:
                // キャンセルされた
                //  -- 実行中を計算スレッドを破棄する --
                if (th.IsAlive)
                {
                    th.Abort();
                }
                Console.WriteLine("-- Cancelされました --");
                break;

            case 1:
                // 計算スレッドが終了した
                Console.WriteLine("-- 計算が終了しました --");
                break;
            }

            // 処理結果を表示
            Console.WriteLine($"@@@@ 計算結果:Count={args.Count} @@@@");
        }