もくじ
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 非同期パターン」がめちゃ参考になった。