■
Windows8のMetroはまだ情報が小出しで、サンプルも難しすぎですがC#のasync/awaitと同じことを、C++でテストしてみました。
create_asyncを使用するためWindows環境では動作しません。Metro環境(WindowsRT)のみです。
Button_Click_1 はボタンを押すと実行される関数です。create_asyncでスレッドを実行しIAsyncAction類をかえすとスレッド間の
煩わしい変換処理を自動で面倒みてくれるようです。
create_task.then内をUIスレッドで処理してくれる点がポイント。
以下が簡単過ぎるサンプル。
#include
using namespace concurrency;class Test
{
public :
Test(){ a_ = 0;}
IAsyncAction^ Compute();
int a_;
int id_;
};IAsyncAction^ Test::Compute()
{
return create_async( [this]{a_ = 100;
id_ = GetCurrentThreadId();WaitForSingleObjectEx(GetCurrentThread(), 1000*5, FALSE); // wait for 5000ms.
});
}DWORD id1,id2;
int pos;
void App3::MainPage::Button_Click_1(....)
{
Test* t = new Test();pos = 0;
id1 = ::GetCurrentThreadId(); // UI thread.
create_task( t->Compute()).then([t]()
{
// Here is UI thread.
int kk = t->a_;
_ASSERT( kk == 100 );id2 = ::GetCurrentThreadId();
_ASSERT( id1 == id2 );
_ASSERT( pos == 10 ); // async/awaitと同じ
_ASSERT( id1 != t->id_ ); // sure!, different from async thread id.});
pos = 10;
}
昔はUIスレッドという言葉はありませんでした。(UIとはUser Interfaceの略。) DOSの延長線上のWindows3.1までは単一メッセージループしかないのですが、まるでマルチスレッドで動作しているかのような偽装工作をしていました。本格的なスレッドはWindows NTからです。Windows95も確か偽装スレッドだったはずです。なのでUIスレッドはメッセージループとほぼ同じです。UIスレッドではない別スレッドからUIをいじる場合(Textboxの文字を変えるとかListboxに行を挿入など)、間にPostMessageをいれてスレッド間の調整をする必要があり、面倒でしたが、async/awaitは表向きの処理がすべてUIスレッドで実行されるため楽になるようです。
ちなみに、Windows95ころの標準的メモリのサイズは0.008GByteでした。