介紹在Visual Studio 2015 Update 2使用C++\CX的新特性。
在C# 5.0的時候帶來了Async Await的非同步開發模式,這是針對API如果會超過約10ms的API進行非同步的處理方式。
而在C#的Async Await的使用方式大致如下
public async Task HttpDownloadAsync(Uri uri)
{
try
{
using (var client = new HttpClient())
using (var response = await client.GetAsync(uri))
{
response.EnsureSuccessStatusCode();
var responseStr = await response.Content.ReadAsStringAsync();
System.Diagnostics.Debug.WriteLine(responseStr);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
這樣就是使用HttpClient抓取Http的資料,但是在C++還是沒有像C#這麼方便可以直接使用Async Await的語法來建立非同步的API Callback。
以下程式碼使用C++\Cx的語法來建立非同步的CallBack。
void CppApp1::MainPage::DoThingPPLAsync()
{
auto picker = ref new FileOpenPicker();
picker->FileTypeFilter->Append(L".png");
picker->FileTypeFilter->Append(L".jpg");
picker->FileTypeFilter->Append(L".jpeg");
picker->FileTypeFilter->Append(L".gif");
picker->ViewMode = PickerViewMode::Thumbnail;
picker->SuggestedStartLocation = PickerLocationId::Desktop;
create_task(picker->PickSingleFileAsync()).then([this](Windows::Storage::StorageFile^ file)
{
create_task(file->OpenReadAsync()).then([this](Windows::Storage::Streams::IRandomAccessStreamWithContentType^ fileStream)
{
auto bImg = ref new BitmapImage();
create_task(bImg->SetSourceAsync(fileStream)).then([this, bImg](void)
{
this->ProfileImage->Source = bImg;
});
});
});
}
這邊要說明到create_task是在C++\Cx的建立Task的方式,但是這樣的寫法就是變成如上地巣狀Callback,降低了可讀性以及語法上的直觀。使用create_task需要再header檔案include ppltask如下所示
#include <ppltasks.h>
並且加上concurrency的namespace
using namespace concurrency;
以上是基礎的使用非同步的c++\cx語法。
接者在來說使用pplawait的非同步的方式,如下所示需要include pplawait的header並且調整Project 的屬性,並在Platform toolset的調整成Visual C++ Compiler Nov 2013 CTP (CTP_Nov2013)!
#include <pplawait.h>
void CppApp1::MainPage::DoThingAsync2()
{
auto picker = ref new FileOpenPicker();
picker->FileTypeFilter->Append(L".png");
picker->FileTypeFilter->Append(L".jpg");
picker->FileTypeFilter->Append(L".jpeg");
picker->FileTypeFilter->Append(L".gif");
picker->ViewMode = PickerViewMode::Thumbnail;
picker->SuggestedStartLocation = PickerLocationId::Desktop;
auto file = __await picker->PickSingleFileAsync();
auto fileStream = __await file->OpenReadAsync();
auto bImg = ref new BitmapImage();
__await bImg->SetSourceAsync(fileStream);
this->ProfileImage->Source = bImg;
}
那麼接者來介紹VS 2015 Update 2所加入的新功能,先是在header的部分宣告非同步的method
concurrency::task<void> DoThingAsync();
接者在CPP檔案實作該非同步方法
#include <experimental\resumable>
task<void> CppApp1::MainPage::DoThingAsync()
{
auto picker = ref new FileOpenPicker();
picker->FileTypeFilter->Append(L".png");
picker->FileTypeFilter->Append(L".jpg");
picker->FileTypeFilter->Append(L".jpeg");
picker->FileTypeFilter->Append(L".gif");
picker->ViewMode = PickerViewMode::Thumbnail;
picker->SuggestedStartLocation = PickerLocationId::Desktop;
auto file = co_await picker->PickSingleFileAsync();
auto fileStream = co_await file->OpenReadAsync();
auto bImg = ref new BitmapImage();
co_await bImg->SetSourceAsync(fileStream);
this->ProfileImage->Source = bImg;
}
這邊include的是從C++ 11的非同步語法延伸過來的非同步概念!語法上使用的co_await和C#的Async await非常相近,這樣的寫法提高了C++的可讀性。這樣在C++\CX上撰寫非同步的Code就比較容易上手拉~基本上在UWP調用Perofmance focus的API時撰寫C++\Cx的效能會獲得大量提升(當然也是要撰寫的正確運算邏輯才會有效果)。
***以上Code以及說明都有可能隨著Windows 10 的版本以及Visual Studio 2015版本有所調整!***
參考資料 Asynchronous programming with C++ UWP
下次再分享Windows 10 的新技術拉~