2019年03月17日
川俣晶の縁側ソフトウェア技術雑記total 2156 count

非同期メソッドではないにも関わらず、CancellationTokenSource.Cancelメソッドは同期的に実行されない

Written By: 川俣 晶連絡先

問題 §

 以下のプログラムでXYZ0,XYZ1,XYZ2,XYZ3の順番を期待したのに、実際はXYZ0,XYZ2,XYZ3,XYZ1である。

using System;

using System.Threading.Tasks;

namespace CancelToken1

{

    class Program

    {

        static async Task Main(string[] args)

        {

            try

            {

                var source = new System.Threading.CancellationTokenSource();

                _ = Task.Delay(1000).ContinueWith((task) =>

                 {

                     Console.WriteLine("XYZ0");

                     source.Cancel();

                     Console.WriteLine("XYZ1");

                 });

                await Task.Delay(-1, source.Token);

            }

            catch (System.Threading.Tasks.TaskCanceledException)

            {

                Console.WriteLine("XYZ2");

            }

            Console.WriteLine("XYZ3");

        }

    }

}

原因 §

 source.Cancel();は非同期メソッドではないにも関わらず非同期的に実行される。つまり、Cancelメソッドは即座に待機中のメソッド(Delay)で例外(TaskCanceledException)を発生させるため、待機中のDelayメソッドの実行が即座に再開されてしまう。コンテキストスイッチのタイミングがまわってくるまで、Cancelメソッドの次のメソッド(Console.WriteLine("XYZ1");)は実行されない。

解決 §

 待機中のメソッドが再開する前に実行すべきコードはCancelメソッドの呼び出しよりも手前に必ず置く。

 たとえば以下のように書き換える。

                     Console.WriteLine("XYZ0");

                     Console.WriteLine("XYZ1"); // 移動された行

                     source.Cancel();

Facebook

キーワード【 川俣晶の縁側ソフトウェア技術雑記
【技術雑記】の次のコンテンツ
2019年
03月
18日
Web AssemblyとBlazorのマルチスレッド対応はどうなっているのか
3days 78 count
total 2166 count
【技術雑記】の前のコンテンツ
2019年
03月
05日
VisualStudio 2017用VSIXを2019対応させる方法
3days 77 count
total 2368 count

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

http://mag.autumn.org/tb.aspx/20190317120209
サイトの表紙【技術雑記】の表紙【技術雑記】のコンテンツ全リスト 【技術雑記】の入手全リスト 【技術雑記】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.34 (Alpha-Test) Copyright (c) 2004-2018 Pie Dey.Co.,Ltd.