AzureをプラットフォームにしてASP.NETで、戻りを待つ必要のないおもし蟹な重い処理をバックグラウンド処理として実装したいなーと思うと、
- QueueBackgroundWorkItem でサクッと実装?
- WebJobsでささっと実装
- Worker Roleで?
- Azure Batchでごりっごり...
その他、Web Roleなどもあると思いますが、それはさておき...
バックグラウンド処理をする際の手法の選択は、その処理数や処理自体の重さに応じて、どのリソースを使うべきかに応じて選択肢が変わりますでしょうか。
今回は、色んな意味で簡易・容易な QueueBackgroundWorkItem のお話です。
> Environment
サンプルを書いた環境は以下です。
- Visual Studio 2015 (update1)
- ASP.NET MVC5.*
- .Net Framework 4.5.2 以降
DNX周りの話ではないのでご注意を。
1. QueueBackgroundWorkItem 概要
QueueBackgroundWorkItem は、.NET Framework 4.5.2で実装された機能で、それ以前の.NET Frameworkではもちろん使えません。
リリースノートはこちら。
What's New in the .NET Framework
IIS がすべての処理が完了するまで待ってくれるようなので、安心安定ですね。
QueueBackgroundWorkItem は、System.Web.Hosting 名前空間は、HostingEnvironmentクラスのメソッドです。
2つのオーバーロードを持ってます。
- HostingEnvironment.QueueBackgroundWorkItem Method (Action(CancellationToken)) (System.Web.Hosting)
- HostingEnvironment.QueueBackgroundWorkItem Method (Func(CancellationToken, Task)) (System.Web.Hosting)
ざっくりまとめると、
QueueBackgroundWorkItemとは....
「QueueBackgroundWorkItemメソッドにデリゲートを渡せばバックグラウンド処理してくれる」
ということです。
最も簡単に実装できる類のバックグラウンド処理かなーと思ってます。
注意点として、
IISの環境下でバックグラウンド処理をしてくれるので、それ以外だとあたーーーりまめに死にます。
以前、QueueBackgroundWorkItemを使って、Worker Roleで動かないと悩んでいた方が相談に来たことがあったので...念のため書いておきました。
2. QueueBackgroundWorkItem の実装
おもむろにASP.NET MVC5プロジェクトを作り、HomeControllerクラスのIndexメソッドに例を追記してみましょう。
workItemというFuncを定義して渡すだけです。
Funcには、LongLongMethodAsyncメソッドを用意しておきました。
public ActionResult Index() { Func<CancellationToken, Task> workItem = LongLongMethodAsync; HostingEnvironment.QueueBackgroundWorkItem(workItem); return View(); } private async Task LongLongMethodAsync(CancellationToken cancellationToken) { //なんか重い処理... await Task.Delay(10000); }
ActionやFuncを定義せず、ラムダ式で書いてしまうのもよく使いますでしょうか。
public ActionResult Index() { HostingEnvironment.QueueBackgroundWorkItem(cancellationToken => { // なにかおもーい処理を... }); //...以下省略
ラムダか~ら~の~awaitableな何かを呼びたい場合は、QueueBackgroundWorkItemのパラメータの最初にasyncを書いて...
public ActionResult Index() { HostingEnvironment.QueueBackgroundWorkItem(async cancellationToken => { await LongLongMethodAsync(cancellationToken); // なにかおもーい処理を... }); //...以下省略
ですね。
次は、WebJobsを書く予定....