Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

continuatioN Linking

24,262 views

Published on

The "Continuation Passing Style" basics and provide seamless interoperability .NET Task and F# Async workflow implicit conversion technics.

"NLNagoya 2016" conference session slides.

Published in: Software
  • Dating direct: ❶❶❶ http://bit.ly/39mQKz3 ❶❶❶
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Follow the link, new dating source: ❶❶❶ http://bit.ly/39mQKz3 ❶❶❶
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

continuatioN Linking

  1. 1. continuatioN Linking 2016.04.16 NL-NAGOYA 2016 KOUJI MATSUI (@KEKYO2)
  2. 2. 自己紹介 けきょ (@kekyo2, www.kekyo.net) ロードバイク乗り Microsoft MVP for Visual Studio and Development Technology 認定スクラムマスター・スクラムプロダクトオーナー Center CLRオーガナイザー
  3. 3. 最近 というか、かなり昔から「継続」に興味がありまして。 ◦ ブログに連載を始めました ※ 注: 学問的厳密性は無いです
  4. 4. アジェンダ CPS (継続渡しスタイル / Continuation Passing Style) .NET Task / async-await / F# Async workflow Continuation Linking
  5. 5. キーワード: Continuation Passing Style 「継続渡しスタイル」 ◦ 継続渡しスタイル (CPS: Continuation-passing style) とは、プログラムの制御を 継続を用いて陽に表すプログラミングスタイルのことである。 (Wikipedia) 何だ、 名 古 屋 的 ヤ ヴァ イ や つ か。 … 陽に表す、とは
  6. 6. Continuation Passing Style 処理の完了時に、次に実行すべき 処理を渡させる 継続させる処理を関数(ラムダ式) でネストさせて渡していく 一般的な逐次処理
  7. 7. Continuation Passing Style 「継続渡し (Continuation Passing)」 継続させる処理 ≒ コールバック
  8. 8. Continuation Passing Style コールバックで処理を継続させるといえば、 JavaScriptのコールバックハンドラーとかメジャーですね。 「継続渡し (Continuation Passing)」 難しくない!! 「CPS」という名前を付けただけだ!
  9. 9. Continuation Passing Style CPSについてわかりましたか? これが何?という疑問は「沼」なので、ここではスルーします。 ◦ 各自、ググって下さい。 「継続渡し」というものが感覚的に分かればよいです。
  10. 10. アジェンダ CPS (継続渡しスタイル / Continuation Passing Style) .NET Task / async-await / F# Async workflow Continuation Linking
  11. 11. キーワード: .NET Task .NET 4.0から導入された、「タスク」を透過的に扱うクラス。 更に、.NET 4.5とC# 5.0のasync-awaitを使って、非同期処理をタ スクとして扱えるようにした。 CPSと何の関係が?
  12. 12. .NET Task (.NET 4.0 / C# 4.0) まずは、.NET 4.0 TaskのCPS (ContinueWithを使う) 関数に直接継続を渡していないが、 Task.ContinueWithに継続を渡している ≒ CPS 注: 手を抜いてasync使ってます
  13. 13. .NET Task (.NET 4.5/C# 5.0) そして、.NET 4.5/C# 5.0 でのasync-awaitによる非同期処理 これが「継続」だと 分かりますか? async-awaitでもTaskを使う
  14. 14. .NET Task comparison つまり、async-awaitによるTaskの継続も、 「構文糖」と見なせば一種のCPSです。 …たぶん これが .NET 4.0 (C# 4.0 Task only) こうなる .NET 4.5 (C# 5.0 async-await)
  15. 15. キーワード: F# Async workflow F# 2.0から導入された「非同期ワークフロー」。 非同期処理をシームレスにF#構文に統合(.NET 2.0以降) CPSと何の関係が?
  16. 16. F# Async workflow ほとんどasync-awaitと一緒 これが「継続」だと分かりますか? 返されるのは Async<int> ※ let! (Let-Bang) は、Async<T>を非同期処理として待機して、結果のTを束縛します。 C#でのawaitに相当。 ※ F# Async workflowのCPSは長いので省略。 Async.FromContinuations<T>関数を使います。
  17. 17. 非同期継続のまとめ .NET Task : ContinueWith .NET Task : async-await F# Async workflow : let! それぞれの非同期処理の継続手段が、暗に「CPS」であることが わかりましたか?
  18. 18. アジェンダ CPS (継続渡しスタイル / Continuation Passing Style) .NET Task / async-await / F# Async workflow Continuation Linking
  19. 19. 「継続」を「接続」する .NET TaskとF# Asyncをシームレスに接続して、相互運用可能に できたらいいね。 ◦ 大枠において対比出来る、Task<T> ⇔ Async<T> という関係から妄想 つまり: ◦ F# AsyncをC#側でawait出来たらいいよね? ◦ .NET TaskをF# Async workflowでlet!出来たらいいよね? ◦ HttpClient.GetStreamAsync()とか、普通にuse!できるようになるよ。
  20. 20. .NET Task / C#側のシナリオ Async<T>クラスに対して拡張メソッドを定義して「AsTaskメ ソッド」を生やし、 Async<T> →Task<T>に変換可能にする。 ◦ Async.StartWithContinuations<T>関数を使って、TaskCompletionSource<T> を操作(SetResult・SetException・SetCanceled)し、Task<T>クラスを返 す。 Async<T>クラスに対して拡張メソッドを定義して「GetAwaiter メソッド」を生やす。 ◦ C# でAsync<T>に対して直接awaitが可能になる。 ※ F#のAsync<T>クラスは、正確にはFSharpAsync<‘T>クラスです。
  21. 21. .NET Task / C#側のシナリオ Async<int>を直接awaitで待機 (GetAwaiterが呼ばれる)
  22. 22. F# Async workflow側のシナリオ Asyncクラスに対して拡張関数を定義して「AsAsync関数」を生 やし、Task<T>→Async<T>に変換可能にする。 ◦ Async.FromContinuations<T>関数を使って、Task.ContinueWithメソッドの コールバックからAsync<T>の継続を操作する。 AsyncBuilder<T>クラスに対して拡張関数を定義して「Source関 数」を生やす。 ◦ Source関数がTask<T>を受け取りAsync<T>に変換することで、F# Async workflow内で直接let! が可能になる。 ※ let!の他にdo!・return!・use!もありますが、Source関数を定義することでこれらすべ てに対応できます。
  23. 23. F# Async workflow側のシナリオ Task<int>を直接let!で待機 (Sourceが呼ばれる)
  24. 24. こまごまとしたシナリオ System.VoidとFSharp.Unitの、型安全な変換の考慮 ◦ Async<unit>をawaitすると、戻り値を受け取れないようにする。 ◦ Task(非ジェネリック)は、do!しかできないようにする。 CancellationTokenのサポート ◦ F#側はAsync workflowのコンテキスト中で共通に割り当てられるTokenが存在 するが、Task側にはそのような概念はない。 ◦ AsTask/AsAsyncで変換する際に、明示的に渡せるようにする。 Async.RunSynchronous関数を使わない ◦ 使ったらハードブロックしてしまう。Task.Waitメソッドを呼び出すことに該 当。FromContinuations<T>やStartWithContinuations<T>を使う。 AsyncCompletionSource<T>を作る ◦ FromContinuations<T>はコールバック関数を基礎としているので扱いにくい。 TaskCompletionSource<T>に相当する、F# Asyncの委譲クラスが必要。
  25. 25. ご清聴ありがとうございました! これで実装してます→ GitHub: FusionTasks ◦ https://github.com/kekyo/FSharp.Control.FusionTasks ◦ https://www.nuget.org/packages/FSharp.Control.FusionTasks.FS40/ スライドはブログに上げます ◦ http://www.kekyo.net/ ※ Thx: JavaScript プログラミング解説 http://so-zou.jp/web-app/tech/programming/javascript/event/handler/

×