なか日記

一度きりの人生、楽しく生きよう。

非同期コントローラー

気がつけばこのブログ、ただの勉強会参加メモブログになっててひどいことに。
どげんかせんといかんと思いながらも放置状態が続いていましたが、少しずつでも何か残していこうと思います。

というわけで、先行予約して発売日よりも早く、そして安く手に入れてたけど全然開けてなかったこの本を読み進めて、メモを残してみようそうしよう。

読み始めていきなり非同期コントローラーというのを知ったのでメモ。

通常のコントローラー

    public class Part1Controller : Controller
    {
        //
        // GET: /Part1/PerformTask/
        public ActionResult PerformTask()
        {
            // 時間がかかる処理(Webサービスの参照とか)
            System.Threading.Thread.Sleep(5000);
            
            var result1 = new ResultDataModel {Id = 1, Name = "nakaji"};

            return View(result1);
        }
    }

非同期コントローラー

これを非同期コントローラーに書き直すとこんな感じ。

    public class Part1Controller : AsyncController
    {
        public void PerformTaskAsync()
        {
            AsyncManager.OutstandingOperations.Increment();
            
            // 時間がかかる処理(Webサービスの参照とか)
            System.Threading.Thread.Sleep(5000);

            AsyncManager.Parameters["result1"] = new ResultDataModel {Id = 1, Name = "nakaji999"};
            AsyncManager.OutstandingOperations.Decrement();
        }

        public ActionResult PerformTaskCompleted(ResultDataModel result1)
        {
            return View(result1);
        }
    }
ポイント
  • 継承するコントローラーが「Controller」から「AsyncController」に変わる
  • メソッドがトリガーメソッドとファイナライザーメソッドに分割
    • トリガー:リクエストの準備(時間がかかる処理を開始)
    • ファイナライザー:リクエストの完了
  • トリガーからファイナライザーへはAsyncManager.Parametersを使ってパラメーターの受け渡しを行う
  • AsyncManagerのOutstandingOperationsプロパティは保留状態にある非同期クラスの数を管理する
    • Incrementした分をきっちりDecrementしないとファイナライザーが実行されないみたい

ちなみに、利用者(ブラウザ)から見ると同期も非同期も動作は同じで、サーバのASP.NETプールのスレッドに要求される処理が少なくなるとか。小規模サイトでは特に気にしなくてもよさげですね。