きな粉もち.net

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

Task.Start ×Task.Run × TaskFactory.StartNew

この記事の目的

この記事では、
Taskを開始するメソッドのベストチョイスを探し出すこと
を目的としています。

Google翻訳に手伝ってもらいながら訳したMSDNの説明をもとに考えていきます。

本題

★Start

MSDNの説明を訳してみました。

      • -

タスクは1回だけ起動して実行できます。
2回目にタスクをスケジュールしようとすると、例外が発生します。
Startは、Taskコンストラクタの1つを呼び出して作成されたタスクを実行するために使用されます。
通常は、作成したタスクを条件付きで実行する場合など、タスクの作成を実行から切り離す必要がある場合にこれを行います。
タスクインスタンス化を実行から分離する必要がないような一般的なケースでは、Task.RunまたはTaskFactory.StartNewメソッドのオーバーロードを呼び出すことをお勧めします。

      • -

Startを利用するのは、
タスクの作成を実行から切り離す必要がある場合
で、それ以外は、Task.RunやTaskFactory.StartNewが推奨されています。

★TaskFactory.StartNew

MSDNの説明を訳してみました。

      • -

.NET Framework 4.5以降、タスクを起動するには、Task.Runメソッドをお勧めします。
StartNewメソッドを使用するのは、実行時間の長い計算処理タスクに対して細かい制御が必要な場合のみです。
これには、以下を制御するシナリオが含まれます。

1)タスク作成オプション。
既定でTask.Runメソッドによって作成されたタスクは、TaskCreationOptions.DenyChildAttachオプションを使用して作成されます。
この動作をオーバーライドする、または他のTaskCreationOptionsオプションを提供するには、StartNewオーバーロードを呼び出します。

2)パラメータ渡しのオプション。
Task.Runメソッドのオーバーロードは、タスクデリゲートにパラメータを渡すことを許可しません。
StartNewメソッドのオーバーロードはこれを行います。

3)タスクスケジューラのオプション。
Task.Runメソッドのオーバーロードは、デフォルトのタスクスケジューラを使用します。タスクスケジューラを制御するには、スケジューラパラメータを使用してStartNewオーバーロードを呼び出します。

      • -

タスクの実行には、Task.RunをTask.Runを利用することが推奨されています。
ただ、Taskの実行に関して、細かい制御が必要な場合には、StartNewの(たくさんある)オーバーロードが必要になるため、こちらを利用することになる。ということみたいです。

★Run

MSDNの説明を訳してみました。

      • -

Runメソッドは、デフォルト値を使用してタスクを開始するのを容易にする一連のオーバーロードを提供します。
これは、StartNewのオーバーロードに対する軽量の代替手段です。

      • -

第一候補:Task.Run。以上。的な感じです(´∀`=)

まとめ

疑っていたわけではありませんが、
いろいろなブログでも紹介されているように、
第一候補は、Run。
それ以外の特別なシナリオのとき、
適宜StartNew、Startを選択するというのがベストチョイスでした。

理由は、タスク生成時のオプションを指定する手間を省けるから。といったところでしょうか。