windows 8時代のuxを支える非同期プログラミング

Post on 12-Nov-2014

2.878 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

TRANSCRIPT

時代の を支える非同期プログラミング

グレープシティ株式会社

八巻雄哉

本日のお話し

2

これまで

非同期処理の必要性、および需要

非同期処理実装の難易度

低 高

低 高

3

これから( 時代)

非同期処理の必要性、および需要

非同期処理実装の難易度

低 高

低 高

4

“非同期処理”って何?

5

“非同期処理”って何?

同期処理

一つの処理が終わるまで次の処理が行われない

非同期処理

前の処理とは関係なく次の処理が行われる

6

人間とプログラムの違い

人間は意識しなくとも非同期的に動いている

プログラムは何もしないと同期的にしか動かない

この違いがユーザーエクスペリエンスの低下を生む

7

もしも人間がプログラムのように動いたら

レストランの業務をプログラム化してみる

8

「 」イベントハンドラ

10

「注文が決定する」イベントハンドラ

注文が決定する注文決定イベント引数

注文 注文を得る テーブル番号

材料 材料を得る注文

レシピ レシピを得る注文

料理 レシピ作成する材料

提供する 料理 テーブル番号

11

料理が完成するまでは一切何もできません

「呼び出しボタン」 を押す 注文が決定する 注文決定イベント引数

注文 注文を得る テーブル番号

材料 材料を得る 注文

レシピ レシピを得る 注文

料理 レシピ作成する 材料

提供する 料理 テーブル番号

料理が 運ばれてくる

12

お客さん 料理店の人

ボタンを押すと結果が返るまで は応答不能

ボタン を押す 注文が決定する 注文決定イベント引数

注文 注文を得る テーブル番号

材料 材料を得る 注文

レシピ レシピを得る 注文

料理 レシピ作成する 材料

提供する 料理 テーブル番号

結果がUI上に 表示される

13

ユーザー メインスレッド

非同期処理の種類

① 非ブロッキング (非同期 )

をブロックしないための非同期処理

② 並列処理(計算)

データ並列

タスク並列

14

非同期化する方法

15

非同期化する方法

マルチスレッド化

メインスレッドはユーザーの入力( からの指示)を待ち受けるためのスレッドとし、料理を作る処理は別のスレッドにお願いする

レストランの例では

接客専任のホールスタッフを雇う

16

スレッドを使用SynchronizationContext ctx = SynchronizationContext.Current;

ThreadPool.QueueUserWorkItem(_ =>

{

var 注文 = 注文を得る(e.テーブル番号);

var 材料 = 材料を得る(注文);

var レシピ = レシピを得る(注文);

var 料理 = レシピ.作成する(材料);

ctx.Post(state =>

{

提供する(料理, e.テーブル番号);

}, 料理);

});

17

非同期プログラミングの難しさ

18

①新しくスレッドを生成するのは思った以上にコストがかかる

注文を受ける度に新しくスレッドを生成するのは効率が悪い

ではあらかじめ用意されたスレッドをできる限り再利用するスレッドプールという仕組みがある

レストランの例では

新しく人を雇うのには意外とコストがかかる

19

②順序やタイミングが大切な処理は必ず存在する

別スレッドで実行した処理の継続処理、および完了待ち

お互いがスレッドの完了を待ち続けるデッドロックや共有メモリへのアクセスによる競合状態

レストランの例では

一人のときは全部自分がやっていたから問題が起きなかったが、二人以上では協調して動かなければならない

20

③ コンポーネントへのアクセスは、その コンポーネントを作成したスレッドで行わなければならない実行結果を 上に表示するといった場合、

必ず スレッドに処理を委譲する必要がある

レストランの例では

料理人が自分で料理をお客さんに出したほうが早いのに、運ばせてくれない

21

④スレッドプログラミングの怖さはテストのしにくさ

回動作したから正しいという保証もないし、回動作したから正しいという保証もない

レストランの例では

人を管理するのはとても大変で、想像もしない行動を起こすこともある

22

非推奨

よほどのことがない限り、直接スレッドをどうこうしようと思ってはいけない

マイクロソフト株式会社コンサルティングサービス統括本部プリンシパルコンサルタント赤間信幸氏いわく

やはり個人的におすすめしたいのは、マルチスレッドアプリケーションはなるべく作らない。これに尽きます。

23

.NETにおける非同期処理簡便化

24

ライブラリとコンパイラの進化

非同期動作を公開するためのパターン

IAsyncResultパターン(.NET 1.0~)

イベントベースの非同期パターン(.NET 2.0~)

タスクベースの非同期パターン(.NET 4.0 ~ )

タスクベースの非同期パターンを 簡便に記述するための新たな構文

async/await構文(.NET 4.5、Windows Runtime)

25

タスク並列ライブラリ

26

タスク並列ライブラリ

( )

名前空間

名前空間

タスクとして思考すればよく、スレッドに対する深い知識は不要

タスク並列ライブラリを使うことで、処理が簡略化されるだけでなく、効率よく実行できる

非同期処理を簡単に操作、および構成するメソッドを持つ

タスクを使用var uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();

Task<Meal> task = Task.Factory.StartNew(() =>

{

var 注文 = 注文を得る(e.テーブル番号);

var 材料 = 材料を得る(注文);

var レシピ = レシピを得る(注文);

var 料理 = レシピ.作成する(材料);

return 料理;

});

task.ContinueWith(t =>

{

提供する(t.Result, e.テーブル番号);

}, uiTaskScheduler);

28

タスクベースの非同期パターン

29

タスクベースの非同期パターン

( )

標準クラスライブラリには、時間のかかる処理においてタスクベースの非同期メソッドが用意されている

を返す 、およびメソッド

タスクの継続と待機

継続

待機

メソッド一つのタスクに対して、継続タスクを指定する

メソッド継続元タスクが複数存在する状態で、その全てが完了した場合に継続する

メソッド継続元タスクが複数存在する状態で、そのどれかが完了した場合に継続する

メソッドタスクを待機させる

メソッド指定された複数のタスクを待機させる

メソッド指定された複数のタスクの内、どれかが完了するまで待機させる

肉を焼いてから野菜を切るvar ターキー = (肉)材料[0];

味をつける(ターキー);

オーブンで焼く(40, ターキー);

var サラダ用野菜 = (野菜)材料[1];

切る(サラダ用野菜);

皿に盛り付ける(サラダ用野菜);

皿に盛り付ける(ターキー);

32

肉を焼いている間に野菜を切るvar ターキー = (肉)材料[0];

味をつける(ターキー);

Task task1 = オーブンで焼くAsync(40, ターキー);

var サラダ用野菜 = (野菜)材料[1];

Task task2 = 切るAsync(サラダ用野菜);

task2.ContinueWith(_ =>

{

Task task3 = 皿に盛り付けるAsync(サラダ用野菜);

});

Task.WaitAll(task1, task2);

皿に盛り付ける(ターキー);

33

async/await構文

34

構文

メソッドに 修飾子、非同期処理(タスクベースの非同期版メソッド)の手前に キーワードをつけるだけ

同期処理とほぼ同様のコードをコンパイラが機械的にタスクを使った非同期処理へと変換してくれる

スレッドをブロックすることなくメソッドの実行を一時停止したり再開したりできるポイントをメソッドに埋め込む

同期版

注文が決定する注文決定イベント引数

注文 注文を得る テーブル番号

材料 材料を得る注文

レシピ レシピを得る注文

料理 レシピ作成する材料

提供する料理 テーブル番号

36

非同期版

注文が決定する注文決定イベント引数

var 注文 = await 注文を得るAsync(e.テーブル番号);

var 材料 = await 材料を得るAsync(注文);

var レシピ = await レシピを得るAsync(注文);

var 料理 = await レシピ.作成するAsync(材料);

提供する(料理, e.テーブル番号);

37

async/await構文使用時の実行順序

38

同期版メソッド

39

private void Button_Click_1(object sender, RoutedEventArgs e)

{

Download();

debugList.Items.Add("コアラ");

}

private void Download()

{

debugList.Items.Add("パンダ");

HeavyTask();

debugList.Items.Add("うさぎ");

}

同期版の実行順序

40

Download();

debugList.Items.Add("パンダ");

HeavyTask();

debugList.Items.Add("うさぎ");

debugList.Items.Add("コアラ");

private void Download()

private void Button_Click_1(…)

時間のかかる処理

非同期版メソッド

41

private void Button_Click_1(object sender, RoutedEventArgs e)

{

Download();

debugList.Items.Add("コアラ");

}

private async void Download()

{

debugList.Items.Add("パンダ");

await HeavyTaskAsync();

debugList.Items.Add("うさぎ");

}

非同期版の実行順序

42

Download();

debugList.Items.Add("パンダ");

debugList.Items.Add("コアラ");

debugList.Items.Add("うさぎ");

await HeavyTaskAsync();

中断

再開

private async void Download()

private void Button_Click_1(…)

時間のかかる処理

非同期プログラミングの重要性

43

高まる非同期処理の重要性

① タッチ における応答継続の重要性

“ ” (指に吸い付く )

タッチ は基本的に全画面

② ネット世代における

ブラウザーは常に非同期

③ マルチコア時代

ムーアの法則の恩恵を受けるためにも

44

高まる非同期の必然性

側から

の場合非同期版メソッドが用意されているのは、

主に通信&データにおける のみ

スタイルアプリ/ の場合

実行に ミリ秒以上の時間がかかる可能性のあるメソッドはすべて非同期化されている

システム( )側から

では、メインスレッドが 秒以上応答しなければ強制終了

45

Metroスタイルアプリ用のWinRT API

基礎部分

認証 暗号化 グローバリゼーション

.NET Win32 アプリの 有効期間

通信 & データ

コントラクト XML Web

ネットワーク 通知

ローカル & クラウドストレージ メディア

キャプチャ

リモート再生

デバイス

センサー

地理位置情報

ポータブルデバイス

NFC

ユーザー インターフェイス

HTML5/CSS XAML DirectX コントロール

入力 アクセシビリティ 印刷

データバインディング

タイル

ストリーム

バックグラウンド転送

SVG

AtomPub

SMS

プリンター

視覚効果

コード変換

46

時代に向けて

スタイルアプリ開発では多くの処理を非同期にせざるを得ない

時代はフリーズしない が当たり前

スタイルアプリの開発では、、 、 言語( / )

の 種類がありますが、/ のように同期操作と

ほぼ同等の記述ができるのは 言語だけ

47

top related