Task で非同期処理をつくる(.NET Framework 4.0用) (゜A゜)

第3回 TaskクラスとPLINQ(Parallel LINQ) − @IT を参考に非同期処理を実装してみる。

なお、.NET Framework 4.5 、C#5.0から提供される async, await での実装はしていません。
.NET Framework 4.0 での実装時の参考にしてください。

環境

目的

Webアプリで時間のかかる処理を実行しつつ、Responseは返して画面描画は完了させる。

並行処理

参考にした記事では、task.Wait() を処理待ちをしていたけどWebアプリ想定として処理待ちはしません。また、WebのResponse送信完了後も処理が継続していることを確認するためにnotify()を完了後に実行するよう、task.ContinueWith()で指定してます。

public class TaskService
{
    private NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

    void notify(Task t)
    {
        logger.Info("ヽ(*゚д゚)ノカイバー {0} done", t.Id);
    }

    public void Execute()
    {
        var task = Task.Factory.StartNew(() =>
        {
           // 長い処理
            for (int i = 0; i < 10000; i++) logger.Info("ヽ(*゚д゚)ノカイバー");
        }).ContinueWith(notify);

        for (int i = 0; i < 100; i++) logger.Info('A');
    }
}

クラスは以下の通り。ASP.NET MVC のコントローラです。

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "ヽ(*゚д゚)ノカイバー";
        var service = new TaskService();
        service.Execute();
        TaskService.Execute();
        return View();
    }
}

出力したログの結果は以下の通り。

2012-09-21 01:05:06.4620 INFO A
 ~中略~
2012-09-21 01:06:56.8451 INFO ヽ(*゚д゚)ノカイバー
2012-09-21 01:06:56.8591 INFO ヽ(*゚д゚)ノカイバー
2012-09-21 01:06:56.8722 INFO ヽ(*゚д゚)ノカイバー
2012-09-21 01:06:56.8862 INFO ヽ(*゚д゚)ノカイバー
2012-09-21 01:06:56.8862 INFO ヽ(*゚д゚)ノカイバー
2012-09-21 01:06:56.9142 INFO ヽ(*゚д゚)ノカイバー
2012-09-21 01:06:56.9292 INFO ヽ(*゚д゚)ノカイバー
2012-09-21 01:06:56.9442 INFO ヽ(*゚д゚)ノカイバー
2012-09-21 01:06:56.9582 INFO ヽ(*゚д゚)ノカイバー 1 done