きな粉もち.net

.NET関連仕事に携わっています。OSSのソースを読んで気がついたことを中心に呟いたりブログに投稿したりしています。最近はUiPathを使ったRPAも研究中。気軽にフォローやツッコミよろしくおねがいします! Gitはここを使っています https://github.com/kinakomotitti

基礎学習 × .NET Framework の非同期処理を見直してみた × その3

この記事の目的

この記事では、
Taskクラスの基本的?な使い方をまとめること
を目的としています。

本題

★Taskクラスでよく使われるメソッドとは?

Intericodeでは以下のメソッドがよく使われる項目として表示されました。
f:id:kinakomotitti:20180608211952p:plain

InteriCodeについては、以下のページに詳細が記載されています。
www.visualstudio.com


★Task.Run

Taskのインスタンスを作成し、すぐにタスクを実行します。
Taskに後続のタスクを設定しない場合、このメソッドを利用することになります。

★Task.Start

StartメソッドはRunメソッドとは違い、Taskのインスタンスを作成した後、任意のタイミングでタスクを実行します。
こちらは、後続のタスクを設定した後にタスクを実行させたい場合に利用することになります。
また、以下のように定義することで、Runメソッドのように実行することも可能です。
ということで、今のところRunとStartの明確な使い分けができません(=_=)
人気があるのは、Runメソッドということですが(´▽`)

new Task(() => { /*何か処理*/}).Start();

★親Task、子Task

親タスク、子タスクを設定するには、タスクを定義するとき、TaskCreationOptionsのAttachedToParentオプションを指定します。

親に紐づいているタスク(子タスク)は、親タスクの完了時には完了していることが保証されますが、
紐づいていないタスクは、それが保証されません。
TaskCreationOptionsを注意深く見ないと、思わぬバグを仕込みそうです。。。
今のところ、実際の開発で使ったことも使う予定もないのでピンときません( ゚Д゚)

★条件付き実行処理

Task.ContinueWithメソッドを利用することで、元のタスクの完了時に指定したタスクを実行させることができます。
複数回ContinueWithを呼び出し、複数のタスクを元のタスクに紐づけることもできます。
この複数回ContinueWthメソッドを呼び出す方法は大きく2つあると思っています。
それらの2つの場合を意識して実装したコードと、それらの実行結果は以下の通りです。
1つ目:常に元タスクのインスタンスに対してContinueWithする場合
元タスクが完了したとき、元タスクにContinueWithが一斉に開始されます。
以下の例では、3つContinueWithしていたので、元タスク完了時にスレッドが3つ使われて処理が開始されました。

2つ目:ContinueWithの戻り値のタスクにContinueWithしていく場合

また、ContinueWithメソッドには、親Task、子タスクと同じようにTaskCreationOptionsを指定することができます。
TaskCreationOptionsには15個のオプションがあります。
Intelicodeでは確認したところ、以下の5つがよく使われているオプションでした。
f:id:kinakomotitti:20180608211937p:plain


特に人気の以下のオプションについて、実行時の違いを比較していきます。
なお、NotOnCanceledと比較できるようにするため、NotOnFaultedはOnlyOnCanceledにしました。
※Noneは省略しましたm(_ _)m
ExecuteSynchronously
NotOnRanToCompletion
NotOnCanceled
OnlyOnCanceled

ExecuteSynchronouslyの実装と実行結果↓

NotOnRanToCompletionの実装と実行結果↓

NotOnCanceled/OnlyOnCanceledの実装と実行結果↓

★Taskのキャンセル

前回のブログでまとめました(/・ω・)/
kinakomotitti.hatenablog.com


まとめ

・処理が終わったタスクの実行結果(成功、失敗、キャンセル)を確認して、
 それに合わせて次の処理を呼び出すという処理が必要な場合、Taskを利用する。
・ContinueWithを利用したタスク処理を実装・レビューするときは、
T askCreationOptionsをよく見て、適切なオプションであるか確認する。