非同期処理そのに。
ストアアプリはスレート/タブレット機でも動かさならんのでパフォーマンス重視、重たい処理のおかげでUIが固まるのを嫌います。なので時間のかかる処理はUIとは独立したスレッドでやれ、と。
たとえばフィボナッチ数を求める。
int fibonacci(int n) {
if ( n < 0 ) n = -n;
if ( n == 0 || n == 1 ) return 1;
else {
return fibonacci(n-1) + fibonacci(n-2);
}
}
再帰しまくる関数です。ボタンをひとつ追加します。
コマンドの紐付けは前回と同じ。
さて、上記の fibonacci() を裏で動かすには <ppltasks.h> を #include し、
using namespace concurrency; した上で create_task() を呼べばいい。
ただし create_task() の引数は Windows::Foundation::IAsyncAction族でなくちゃならん。
create_async() にラムダ式や関数オブジェクトを渡すと IAsyncAction族 を作ってくれるので、
そいつを create_task() に渡します。
// ボタン押されたら async_fibonacci() を呼ぶ
ICommand^ CounterModel::Fibonacci::get() {
return ref new Command(ref new Action([this](Object^) { async_fibonacci();}));
}
// フィボナッチ数を求め、表示する
void CounterModel::async_fibonacci() {
create_task(
// カウント値を引数に fibonacci数を求める
create_async([this]() { return fibonacci(Count); }))
// 答えが出たら表示
.then ([this](int n) { set(n); })
;
}
create_task() のあと .then( 次にする仕事 ) で処理を裏で続けられます。
C#/VBだと async/await とかいう構文で楽できるらしいけど、C++/CXではこれがお作法。
これまでのマトメとして、プロジェクトまるごと ココに置いときます。