Recommended
PPTX
PDF
Unity開発で使える設計の話+Zenjectの紹介
PDF
PDF
Cinemachineで見下ろし視点のカメラを作る
KEY
PDF
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
PDF
PDF
PPTX
PDF
PDF
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
PPTX
リアルタイムリモートデバッグ環境によるゲーム開発イテレーションの高速化【DeNA TechCon 2020 ライブ配信】
PDF
PDF
PDF
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
PDF
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
PDF
MagicOnion~C#でゲームサーバを開発しよう~
PDF
ネットワーク ゲームにおけるTCPとUDPの使い分け
PDF
PDF
View Customize Pluginで出来ること
PDF
PPTX
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
PDF
PDF
PDF
PDF
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
PDF
Reactive extensions入門v0.1
PDF
PDF
How to Make Own Framework built on OWIN
PPTX
未来のプログラミング技術をUnityで -UniRx-
More Related Content
PPTX
PDF
Unity開発で使える設計の話+Zenjectの紹介
PDF
PDF
Cinemachineで見下ろし視点のカメラを作る
KEY
PDF
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
PDF
PDF
What's hot
PPTX
PDF
PDF
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
PPTX
リアルタイムリモートデバッグ環境によるゲーム開発イテレーションの高速化【DeNA TechCon 2020 ライブ配信】
PDF
PDF
PDF
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
PDF
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
PDF
MagicOnion~C#でゲームサーバを開発しよう~
PDF
ネットワーク ゲームにおけるTCPとUDPの使い分け
PDF
PDF
View Customize Pluginで出来ること
PDF
PPTX
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
PDF
PDF
PDF
PDF
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
PDF
Reactive extensions入門v0.1
PDF
Viewers also liked
PDF
How to Make Own Framework built on OWIN
PPTX
未来のプログラミング技術をUnityで -UniRx-
PDF
The History of Reactive Extensions
PDF
Reactive Programming by UniRx for Asynchronous & Event Processing
PPTX
PDF
UniRx - Reactive Extensions for Unity
Similar to Reactive Extensionsで非同期処理を簡単に
PDF
C#次世代非同期処理概観 - Task vs Reactive Extensions
PDF
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
PPTX
PPTX
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
PPTX
PPTX
PDF
PPTX
An other world awaits you
PDF
Windows 8時代のUXを支える非同期プログラミング
PDF
PPTX
PDF
PDF
PDF
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
PDF
PDF
PDF
PDF
Prism + ReactiveProperty入門
PDF
.NET最先端技術によるハイパフォーマンスウェブアプリケーション
PDF
東京Node学園#3 Domains & Isolates
More from Yoshifumi Kawai
PDF
A quick tour of the Cysharp OSS
PDF
A Brief History of UniRx/UniTask, IUniTaskSource in Depth
PDF
Building the Game Server both API and Realtime via c#
PDF
ライブラリ作成のすゝめ - 事例から見る個人OSS開発の効能
PDF
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
PDF
Unity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニー
PDF
Implements OpenTelemetry Collector in DotNet
PDF
Deep Dive async/await in Unity with UniTask(EN)
PDF
The Usage and Patterns of MagicOnion
PDF
True Cloud Native Batch Workflow for .NET with MicroBatchFramework
PDF
Memory Management of C# with Unity Native Collections
PDF
Deep Dive async/await in Unity with UniTask(UniRx.Async)
PDF
PDF
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
PPTX
RuntimeUnitTestToolkit for Unity(English)
PPTX
RuntimeUnitTestToolkit for Unity
PDF
NextGen Server/Client Architecture - gRPC + Unity + C#
PDF
How to make the Fastest C# Serializer, In the case of ZeroFormatter
PDF
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
PDF
ZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPC
Reactive Extensionsで非同期処理を簡単に 1. 2. Profile
Twitter
=> @neuecc
Blog => http://neue.cc/
HNはneuecc 読むときは“のいえ”と読ませてます
ドメイン繋いだだけなので発音するの考えてなかっ
た(のでccは抜きで←発音しにくいですから)
Microsoft MVP for Visual C#(2011/4-)
WP7で作った物
ReactiveOAuth, Utakotoha
WP7の好きなtheme
light + lime
3. 4. 5. Language INtegrated Query
// クエリ構文
var query = from x in source
where x % 2 == 0
select x * x;
// メソッド構文
var query = source
.Where(x => x % 2 == 0)
.Select(x => x * x);
6. 7. LINQのデータソースとは
to Objects to Xml to Sql
配列 XML Database
List<T> (JSON)
Stream
無限リスト
to Events to Asynchronous
TextChanged IO – WebRequest
ジェスチャー Timer – ポーリング
センサー Thread – 長時間かかる処理
MusicPlayer
Reactive Extensions
8. 9. Rxの基本軸は時間
IE<T> length
IE<T>
async
event
IO<T> time
=> IE<T>も乗っかることで「全てのデータソース」が合成可能に!
10. 11. 古き良き同期コード
var req = WebRequest.Create("http://hoge/");
var res = req.GetResponse();
var str = new StreamReader(res.GetResponseStream()).ReadToEnd();
簡単。でも、Silverlight/WP7には同期APIは無い。
UIがブロックされるのダメ絶対
Thread立ててそっちで実行させれば?
まあそうです
でもないものはないのでしょうがない
そのかわり特に気を使わなくても必ずUIノンブロッ
キングになる(※但しCPUヘヴィな処理は除く)
12. しょうがないので非同期で書く
var req = WebRequest.Create("http://hoge");
req.BeginGetResponse(ar =>
{
var res = req.EndGetResponse(ar);
var str = new StreamReader(res.GetResponseStream())
.ReadToEnd();
Dispatcher.BeginInvoke(() => MessageBox.Show(str));
}, null);
-> EndHoge
非同期はBeginHoge
基本、クロージャ全開で書く
面倒くさいけれど、まあこれぐらいなら?
13. ネストするとかなりヤバい
var req = WebRequest.Create("http://hoge");
req.BeginGetResponse(ar =>
{
var res = req.EndGetResponse(ar);
var url = new StreamReader(res.GetResponseStream())
.ReadToEnd();
var req2 = WebRequest.Create(url);
req2.BeginGetResponse(ar2 =>
{
var res2 = req2.EndGetResponse(ar2);
var str = new StreamReader(res2.GetResponseStream())
.ReadToEnd();
Dispatcher.BeginInvoke(() => MessageBox.Show(str));
}, null);
}, null);
14. 15. 内側なのは見た目だけ
var req = WebRequest.Create("http://hoge");
req.BeginGetResponse(ar =>
{ 非同期中に起こる例外はEnd時に戻される
try
{
var res = req.EndGetResponse(ar);
var url = new StreamReader(res.GetResponseStream()).ReadToEnd();
var req2 = WebRequest.Create(url);
req2.BeginGetResponse(ar2 => ここの例外をcatchしてない
{
var res2 = req2.EndGetResponse(ar2);
var str = new StreamReader(res2.GetResponseStream()).ReadToEnd();
Dispatcher.BeginInvoke(() => textBlock1.Text = str);
}, null);
} catchできるのは同じ関数のブロック内だけ
catch(WebException e)
{
Dispatcher.BeginInvoke(() => MessageBox.Show(e.ToString()));
}
}, null);
16. もはやカオスすぎて頭痛い
var req = WebRequest.Create("http://hoge");
req.BeginGetResponse(ar =>
{
try
{
var res = req.EndGetResponse(ar);
var url = new StreamReader(res.GetResponseStream()).ReadToEnd();
var req2 = WebRequest.Create(url);
req2.BeginGetResponse(ar2 =>
{
try
{
var res2 = req2.EndGetResponse(ar2);
var str = new StreamReader(res2.GetResponseStream()).ReadToEnd();
Dispatcher.BeginInvoke(() => MessageBox.Show(str));
}
catch (WebException e)
{
Dispatcher.BeginInvoke(() => MessageBox.Show(e.ToString()));
}
}, null);
}
catch (WebException e)
{
Dispatcher.BeginInvoke(() => MessageBox.Show(e.ToString()));
}
}, null);
17. Reactive Extensionsを使うと
ネストが消滅し完全フラット
拡張メソッド(後で説明します)
WebRequest.Create("http://hoge")
.GetResponseAsObservable()
.Select(res =>
new StreamReader(res.GetResponseStream()).ReadToEnd())
.SelectMany(s => WebRequest.Create(s).GetResponseAsObservable())
.Select(res =>
new StreamReader(res.GetResponseStream()).ReadToEnd())
.ObserveOnDispatcher()
.Subscribe(
s => MessageBox.Show(s),
e => MessageBox.Show(e.ToString()));
内部で発生する例外は全てここで扱える
18. 19. 20. 非同期のもと
非同期パターンは概ね二つ
APM(Asynchronous Programming Model)
BeginXxx-EndXxx
WebRequest.BeginGetResponseとか
EAP(Event-based Asynchronous Pattern)
XxxAsync-XxxCompleted
WebClient.DownloadStringAsync/Copletedとか
将来的には?
Rx(WP7では標準搭載ですが.NET4ではまだ)
Task(.NET4では標準搭載ですがWP7ではまだ)
C# 5.0 Async(まだCTP, 恐らく2年ぐらい先)
21. どっちがいいの?
Rxで使うならAPMのほうが相性良い
APMは上から下まで流れてるが、EAPは最後に発火
させなければならない
これはネストする場合に致命的に面倒
// APM
WebRequest.Create("http://hoge")
.GetResponseAsObservable()
.Subscribe();
// EAP
Subscribe後に発火
var wc = new WebClient();
wc.DownloadStringCompletedAsObservable()
.Subscribe();
wc.DownloadStringAsync("http://hoge");
22. 23. FromEvent(FromEventPattern)
戻り値はIEvent<EventArgs>のIO<T>
public static
IObservable<IEvent<DownloadStringCompletedEventArgs>>
DownloadStringCompletedAsObservable(this WebClient webClient)
{
return Observable.FromEvent<
DownloadStringCompletedEventHandler,
DownloadStringCompletedEventArgs>(
h => h.Invoke, // おまじない
h => webClient.DownloadStringCompleted += h,
h => webClient.DownloadStringCompleted -= h);
}
FromEvent<EventHandler,EventArgs>
24. FromAsyncPattern
FromAsyncPatternの戻り値はデリゲート
つまり自分でInvokeするまで実行されない
拡張メソッドにするなら即実行のほうが便利?
Task.Factory.StartNew的なイメージで
public static IObservable<WebResponse>
GetResponseAsObservable(this WebRequest request)
{
return Observable.FromAsyncPattern<WebResponse>(
request.BeginGetResponse, request.EndGetResponse)
.Invoke();
}
25. 26. 最初の例もこんなにスッキリ
Rxが提供してくれているのは基本的な道具
Rxは「分離しやすい」のも特徴的なメリット
<T>への拡張メソッドや、IO<T>->IO<T>の拡張メ
ソッドなどを作って、すっきりさせよう
WebRequest.Create("http://hoge")
.DownloadStringAsync()
.SelectMany(s => WebRequest.Create(s).DownloadStringAsync())
.ObserveOnDispatcher()
.Subscribe(
s => MessageBox.Show(s),
e => MessageBox.Show(e.ToString()));
27. 28. 29. ところでキャンセルしたい
// Subscribeの戻り値はIDisposableなので、Disposeすればおk
var disposable = AsyncMethod().Subscribe();
disposable.Dispose();
// イベントの場合はデタッチになるよ
var buttonClick = button.ClickAsObservable().Subscribe();
buttonClick.Dispose();
// Listに入れてまとめてDisposeとか
var disposables = new List<IDisposable>();
disposable.Add(button.ClickAsObservable().Subscribe());
disposable.Add(button.ClickAsObservable().Subscribe());
disposable.ForEach(d => d.Dispose());
// IList<IDisposable>はCompositeDisposableというのもある
var disposables = new CompositeDisposable();
disposable.Dispose();
30. 例外処理は?
何も書かない
例外はcatchせずスローされてくる
SubscribeのonErrorに書く
Rxのチェーンで発生した例外を全てcatchする
ここに空のものを書けば例外無視が成立とかも
※Tips:一部メソッドが間に挟まれていると(Publishなど)
場合によってはcatchされなくなることも(Publishは内部
で自前でSubscribeしているためチェーンが途切れてる)
Catchメソッドを使う
例外の型を指定した通常のtry-catchに近いもの
戻り値にEmptyを返せば終了、何か別の値を返せばそ
れを代替として流すということになる
31. 基本的なのはこの3つ
// 何も書かないので例外がスローされてくる
WebRequest.Create("http://hoge")
.DownloadStringAsync()
.Subscribe(Debug.WriteLine);
// SubscribeのonErrorで全てcatch
WebRequest.Create("http://hoge")
.DownloadStringAsync()
.Subscribe(Debug.WriteLine, e => { });
// CatchでWebExceptionだけcatch
WebRequest.Create("http://hoge")
.DownloadStringAsync()
.Catch((WebException e) => Observable.Empty<string>())
.Subscribe(Debug.WriteLine);
32. 33. 34. SelectMany + Zip - 合成の例
AsyncA AsyncB
Result
AsyncC
AsyncA().SelectMany(a => AsyncB(a))
.Zip(AsyncC(), (b, c) => new { b, c });
35. ForkJoin - 並列同時実行
AsyncA
AsyncB
Result
AsyncC
AsyncD
Observable.ForkJoin(AsyncA(), AsyncB(), AsyncC(), AsyncD())
.Select(xs => new { a=xs[0], b=xs[1], c=xs[2], d=xs[3] });
36. 多重from(SelectMany)
AsyncA AsyncB AsyncC Result
var asyncQuery = from a in AsyncA()
from b in AsyncB(a)
from c in AsyncC(a, b)
select new { a, b, c };
37. 38. 39. 40. 41. どんな時に使えるの?
Twitterクライアントを作るわけではないけれど、
ステータスだけTwitterに投稿したい、などはよく
あること(特に最近は何でもTwitterだし)
new OAuthClient(ConsumerKey, ConsumerSecret, accessToken)
{
MethodType = MethodType.Post,
Url = "http://api.twitter.com/1/statuses/update.xml",
Parameters = { { "status", "ここに投稿する文章" } }
}
.GetResponseText() // 投稿して、戻り値を得る
.Select(XElement.Parse) // xmlの場合はパースしたいよね
.Subscribe(); // なにか処理するなり例外処理入れるなり
42. 43. 44. 45. 46. 公式見るのがいいよやっぱり
Data Developer Center - Rx
http://msdn.microsoft.com/en-us/data/gg577609
二つのドキュメントが出ています
Hands-on-Lab
チュートリアル式で触りながら分かりやすく
まず見て欲しい
Design Guidelines
マニュアルみたいなもの
更に深くへ
47.