読者です 読者をやめる 読者になる 読者になる

いろいろ備忘録日記

主に .NET 絡みのメモを公開しています。

タスク並列ライブラリ入門記-001 (タスクの実行, TPL, Task.Factory.StartNew, Wait, WaitAll)

C# TPL


だいぶ前に、TPLについてのメモ書きを書いたままサンプルすらも放置してたのを
今日思い出しまして、今更ながらそのサンプル達をアップ・・・。もうasyncとかawaitな事になってるのに。


大分前にアップした以前の記事は以下からご参照くださいませ。


まずは、タスクの実行についての簡単なサンプル。

  #region TaskSamples-01
  /// <summary>
  /// タスク並列ライブラリについてのサンプルです。
  /// </summary>
  /// <remarks>
  /// タスク並列ライブラリは、4.0から追加されているライブラリです。
  /// </remarks>
  public class TaskSamples01 : IExecutable
  {
    public void Execute()
    {
      //
      // Taskは、タスク並列ライブラリの一部として提供されており
      // 文字通りタスクを並列処理するために利用できる。
      //
      // .NET 4.0まで、非同期処理を行う場合ThreadクラスやThreadPoolクラスが
      // 用意されていたが、利用するのに若干の専門性が必要となるものであった。
      //
      // タスク並列ライブラリは、出来るだけ容易に利用できるようデザインされた
      // 新しいライブラリである。
      //
      // さらにタスク並列ライブラリでは、同時実行の程度を内部で調整してくれることによって
      // CPUを効率的に利用するようになっている。
      //
      // ただし、それでもスレッド処理に関する基礎知識は当然必要となる。
      // (ロック、デッドロック、競合状態など)
      //
      // Taskクラスは、System.Threading.Tasks名前空間に存在する。
      //
      // タスクを利用するのに一番簡単な方法はTaskFactoryのStartNewメソッドを
      // 利用する事である。
      //
      // タスクは内部でスレッドプールを利用しているため、スレッドオブジェクトを
      // 直接作成して開始するよりも軽い負荷で実行できる。
      //
      // タスクにはキャンセル機能がデフォルトで用意されている。(CancellationToken)
      // タスクのキャンセル機能については、別の機会で記述する。
      //
      // タスクには状態管理機能がデフォルトで用意されている。
      // タスクの状態管理機能については、別の機会で記述する。
      //
      
      // 別スレッドでタスクが実行されている事を確認する為に、メインスレッドのスレッドIDを表示
      Console.WriteLine("Main Thread : {0}", Thread.CurrentThread.ManagedThreadId);
      
      //
      // Taskを新規作成して実行.
      //   引数にはActionデリゲートを指定する。(戻り値を後で受け取る場合はFuncデリゲート)
      //
      // Waitメソッドはタスクの終了を待つメソッド。
      //
      Task.Factory.StartNew(DoAction).Wait();
      
      
      //
      // Actionの部分にラムダを指定した版
      //
      Task.Factory.StartNew(() => Console.WriteLine("Lambda : {0}", Thread.CurrentThread.ManagedThreadId) ).Wait();
      
      //
      // 多数のタスクを作成して実行.
      //   Task.WaitAllメソッドは引数で指定されたタスクが全て終了するまで待機するメソッド
      //
      Task.WaitAll(
        Enumerable.Range(1, 20).Select(i => Task.Factory.StartNew(DoActionWithSleep)).ToArray()
      );
    }
    
    private void DoAction()
    {
      Console.WriteLine("DoAction: {0}", Thread.CurrentThread.ManagedThreadId);
    }
    
    private void DoActionWithSleep()
    {
      DoAction();
      Thread.Sleep(200);
    }
  }
  #endregion


実行結果は、例えば以下のようになります。

  Main Thread : 1
  DoAction: 3
  Lambda : 4
  DoAction: 4
  DoAction: 3
  DoAction: 3
  DoAction: 4
  DoAction: 3
  DoAction: 4
  DoAction: 3
  DoAction: 4
  DoAction: 3
  DoAction: 4
  DoAction: 5
  DoAction: 5
  DoAction: 3
  DoAction: 4
  DoAction: 4
  DoAction: 5
  DoAction: 3
  DoAction: 4
  DoAction: 5
  DoAction: 3

================================
過去の記事については、以下のページからご参照下さい。