none
Taskのループ処理について RRS feed

  • 質問

  • .NET Framework 4.0を使用してアプリケーションを作成しています。

    下記のような「Task内で無限ループの処理を行う」ことは問題がないのでしょうか?

    Task.Factory.StartNew(() =>
      {
        while(true)
        {
           // 処理
          Thread.Sleep(1000);
        }
    });

    この場合、スレッドプールで管理されている非同期処理実行用のスレッドの1つをこちらで専有して使ってしまうことになると思われます。

    そういったことは許可されているのでしょうか?

    あるいは「Task内で同じTaskを非同期実行する」ことに問題はないのでしょうか?

    void TaskA()
    {
      // 処理
      // Thread.Sleep(1000);
      Task.Factory.StartNew(TaskA);
    }
    
    // 別の処理から、下記コードを実行する
    Task.Factory.StartNew(TaskA);
    

    この場合、形を変えた再帰処理となり、同じデリゲートがキューとしてスレッドプールに入り続けることになると思います。

    このような質問をしているのは、今までアンマネージドスレッドを使用して下記のような処理を行うことが多かったためです。

    1. 処理Aを実行する(処理に必要な時間はその時によって異なる)
    2. 一定時間待つ(処理Aを終えてから次の処理Aの実行まで一定の時間以上待機して欲しい)
    3. 1に戻る(1~3を長時間実行する)

    上記のような処理の場合、アンマネージドスレッドを使うのが一般的なのでしょうか?

    あるいは便利になってきた非同期処理を用いて綺麗に実装することができるのでしょうか?

    回答よろしくお願いします。

    2015年2月25日 6:44

回答

すべての返信

  • Taskの作成時にTaskCreationOptions.LongRunningを与えれば、(標準のTaskSchedulerであれば)スレッドプールを使わずにタスクを実行してくれます。
    • 回答としてマーク h--s 2015年2月25日 10:22
    2015年2月25日 7:01
  • 長時間使用し続けるタスクはそのオプションを指定してTaskをスタートすればよいということですね。

    わざわざアンマネージドスレッドを作る必要もないようで、助かります。

    回答ありがとうございました!

    参考としてお聞きしたいのですが、スレッドプール管理のスレッドに関しては

    「スレッドプール内のスレッドを長時間使用することは可能であるが、作法上間違っている」

    という認識でよろしいのでしょうか?

    2015年2月25日 10:27
  • MSDN にはこういうページもあります。
    「スレッドプールのスレッドを使用しない場合」を読んでみてください。

    https://msdn.microsoft.com/ja-jp/library/0ka9477y(v=vs.110).aspx

    • 回答としてマーク h--s 2015年2月26日 8:40
    2015年2月25日 13:46
    モデレータ
  • ありがとうございます!

    非常に参考になりました。

    2015年2月26日 6:59