async/awaitのさばき方が難解2


とりあず、async/awaiをパターン化してみました。
Task->IAsyncOperation->create_taskで1つのパターンになるようです。

///////////////////////////////////////////////////////////////////////////////
C#側のWindowsランタイムコンポーネント

private async Task MyFunctionInner(...)
{
// private asyncを宣言し、返り値をTaskでラップ。

await xxxAsync(); // 何とかAsync()はawaitを必ずつける

...

int rval = await xxxAsync();

return rval; // intを返すがTaskになる。裏でコンパイラが自動変換する?
}
public IAsyncOperation MyFunction( ... )
{
// .NET async関数をWinRT async関数へ変換(キャストする)

IAsyncOperation to = MyFunctionInner( ... ).AsAsyncOperation();
return to;
}

//////////////////////////////////////////////////////////////////////////////////
C++/cx側のアプリケーション (C#側のWindowsランタイムコンポーネントを呼び出す側)

#include
using namespace concurrency;

void MainPage::test()
{
Hoge^ cl = ref new Hoge();
create_task( cl->MyFunction( ... ) ).then( [=](int rval ){

// rvalはMyFunctionInnerが返した値
// ここはUIスレッドで動く。(すべてはこのために)

...
});
}

呼び出されたtest()内のcl->MyFunctionはすぐには実行されず、test()を終わらせてUIメッセージループに帰った時に別スレッドから実行されるだろうと思います。


最近はC++C#コンパイラが裏でソースを大幅に書き換えてしまい、何が起きているか理解しずらくなりました。
でも、慣れれば何とかなるでしょう。

参考、.NET タスクを WinRT 非同期処理として公開する(何書いてんのかよくわからないブログ)
http://blogs.msdn.com/b/windowsappdev_ja/archive/2012/06/25/net-winrt.aspx