Taskの状態遷移

もくじ

https://tera1707.com/entry/2022/02/06/144447

やりたいこと

タスクは、作ったり動かしたり、キャンセルしたりで、いろいろ状態が変化する。 その変化を試したときのメモ。

下記のような状態があるらしい。

https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskstatus?view=net-7.0

ためしたこと

Created(0)

// Taskがnewだけされると、Statusが「Created」になる
var t = new Task(() => { Debug.WriteLine("何かのアクション"); });

このページの一番下で参考に挙げた「.NETのクラスライブラリ設計 改訂版」の「9.2 非同期パターン P303」で、このCreateという状態はいらんかったのでは!?これのせいでややこしくなって罠になった!?、みたいなことが書かれてる。

Created状態のタスクを間違えて.Wait()とかすると、永久に待ち続けることになる、とかが罠らしい。確かに。

なので、上に書いたような、TaskのコンストラクタにAction渡してtで受けるようなことはしない方がよさそう。

Running(3)

// TaskがStartされると、Statusが「Running」になる
t.Start();

WaitingForActivation(1)

// TaskがTask.Runで作成と同時にスタートされると、そのTaskのStatusが「WaitingForActivation」になる。
// その後、RanToCompletionになるまで、1のまま。(3にはならなかった)
var t4 = Task.Run(()=>Debug.WriteLine(""));

これが、一回Taskの変数で受けて、.Start()したときと動きがなぜ違うのか、わからなかった...

追記

下記のように、Task.Factory.StartNew()でタスクをスタートすると、t.Start()と同じ挙動になった。
Task.Run()が、なにか特別なのか...?

 taskList.Add(Task.Factory.StartNew(async () =>Debug.WriteLine(""));

WaitingToRun(2)

// 多数のTaskがStartすると、Startできる分だけRunningになり、あとは「WaitingToRun」になる
// ※今回試したときは、最初10個のTaskだけRunningになった。あとは、終わり次第次のTaskがRunningになるという感じ
HashSet<Task> taskList = new HashSet<Task>();
for (int i = 0; i < 50; i++)
{
    var t3 = new Task(() => Thread.Sleep(1000));
    taskList.Add(t3);
}
foreach (var tt in taskList)
    tt.Start();

RanToCompletion(5)

タスクが、問題なく完了したら、5になってた。

Canceled(6) Faulted(7)

別でやる。

参考

タスクの状態の一覧

https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskstatus?view=net-7.0

.NETのクラスライブラリ設計
この本の「9.2 非同期パターン」がめちゃ参考になった。