SlideShare a Scribd company logo
1 of 63
C# 8.0
非同期ストリーム
岩永 信之
今日の話
• C# 8.0の非同期ストリーム
• 非同期メソッドやTaskクラス周りの歴史
• パフォーマンス改善
C# 8.0の他の機能
• Preview版の頃から割と安定していた機能は4月の登壇を参照
• null許容参照型は先月の登壇を参照
Visual Studio 2019 Launch
(https://connpass.com/event/122145/)
C# 8.0 Preview in Visual Studio 2019 (16.0)
(https://www.slideshare.net/ufcpp/c-80-preview-in-visual-studio-2019-160)
Visual Studio Users Community Japan #1
(https://vsuc.connpass.com/event/143114/)
C# 8.0 null許容参照型
(https://www.slideshare.net/ufcpp/c-80-null)
C# 8.0の新機能:
非同期ストリーム
非同期ストリームとは
• 非同期で複数のデータを受け渡し
• 非同期メソッドでyieldを使える = 複数のデータを非同期に返す
• foreachの非同期版が使える = 複数のデータを非同期に受け取る
await Task.Delay(1);
yield return 1;
awaitとyieldの混在
await foreach (var item in source)
{
}
await foreach構文
非同期ストリームの例
• gRPCを例にして非同期ストリームを紹介
• サンプル: NetCoreGrpc
• 背景
• gRPCは非同期ストリームを送受信する想定を持ってる
• streamキーワードを付けると非同期ストリームになる
• ASP.NET Core 3.0はgRPCに対応
• 既存のGoogle.Protobufパッケージを使っていそう
• C# 8.0の非同期ストリームに対応した拡張メソッドも提供
• gRPCのstreamに対してawait foreachを使える
非同期ストリームの例(gRPC)
• サンプル(proto定義)
• Microsoft独自なことはしておらず、普通のProtocol Buffers
service Sample {
rpc GetValues(stream SampleRequest) returns (stream SampleResponse);
}
message SampleRequest {
int32 bits = 1;
int32 length = 2;
}
message SampleResponse {
repeated int32 values = 1;
}
stream って付けておくと
非同期に複数のデータを送れる
例として
• bits桁の数値をlength個要求して
• リスト(repeated)で返してもらう
非同期ストリームの例(コード生成)
• protoからC#コードが生成される
• サーバー側 (生成結果のクラスを派生して使う)
• クライアント側 (生成結果のクラスをnewして使う)
public class SampleService : Sample.SampleBase {
public override async Task GetValues(
IAsyncStreamReader<SampleRequest> requestStream,
IServerStreamWriter<SampleResponse> responseStream,
ServerCallContext context) ...
var client = new SampleClient(channel);
var call = client.GetValues();
call.RequestStream ...
call.ResponseStream ...
送信側
受信側
受信側
送信側
非同期ストリームの例(送信側)
• 一定時間ごとにデータを要求
async Task sender()
{
for (int i = 1; i < 32; i++)
{
await call.RequestStream.WriteAsync(
new SampleRequest { Bits = i, Length = i });
await Task.Delay(500);
}
await call.RequestStream.CompleteAsync();
}
とりあえずちょっと遅延を挟んでおく
複数のデータを送信
(stream)
もうこれ以上送るデータが
ないことを伝える
非同期ストリームの例(サーバー)
• 要求が来るたびにリストを作って返す
var rand = new Random();
await foreach (var req in requestStream.ReadAllAsync())
{
var mask = (1 << req.Bits) - 1;
var len = req.Length;
var res = new SampleResponse();
for (int i = 0; i < len; i++)
res.Values.Add(rand.Next() & mask);
await responseStream.WriteAsync(res);
}
1要求受け取るたびに
そのリストを送る
len要素のリストを作って
非同期ストリームの例(受信側)
• 複数回非同期でリストが届いて、リストの1要素ずつ返す
async IAsyncEnumerable<int> receiver()
{
await foreach (var res in call.ResponseStream.ReadAllAsync())
{
foreach (var value in res.Values)
{
yield return value;
}
}
}
複数のデータを受信
(stream)
受信のたびに複数の値
(repeated)
リストの1要素ずつ返す
非同期ストリームの例(受信側)
• 複数回非同期でリストが届いて、リストの1要素ずつ返す
async IAsyncEnumerable<int> receiver()
{
await foreach (var res in call.ResponseStream.ReadAllAsync())
{
foreach (var value in res.Values)
{
yield return value;
}
}
}
昔だったら
• void receiver(IObservable<int> results)
• → foreachで使いにくい
• Task<IEnumerable<int>> receiver()
• → 1要素ずつ返せない(List<T>とかのバッファー必須)
C# 8.0の言語構文・ライブラリ的な説明
• 非同期メソッドの拡張
• awaitとyieldの混在
• async修飾子を付ける
• 戻り値はIAsyncEnumerable<T>型
• 非同期foreach
• await foreach (var x in asyncStream)
• IAsyncEnumerable<T> (と同じ名前のメソッドを持つ型)を受け付ける
• (おまけで)非同期using
• await using (var x = asyncResource)
• IAsyncDisposable (と同じ名前のメソッドを持つ型)を受け付ける
要求されるフレームワーク
• 非同期ストリームにはIAsyncEnumerable<T>型などが必須
• .NET Standard2.1/.NET Core 3.0では標準提供
• 古いフレームワーク向けのNuGetパッケージ提供あり
• Microsoft.Bcl.AsyncInterfaces
• netstandard2.0/net461でも使える(Unityでも使える)
• ※非同期ストリームがらみだけ異例
• 最近の方針としてはC#と.NETの世代をそろえて使ってほしそう
• 古いフレームワークで最新のC#を使うのは「わかってる人が勝手にやって」
• Range/Indexなどは公式ライブラリ提供なし
• 非同期ストリームがらみはそれだけ需要が高い
IAsyncEnumerable<T>インターフェイス
• IEnumerable<T>の非同期版
public interface IAsyncEnumerable<out T>
{
IAsyncEnumerator<T> GetAsyncEnumerator(
CancellationToken cancellationToken = default);
}
public interface IAsyncEnumerator<out T> : IAsyncDisposable
{
T Current { get; }
ValueTask<bool> MoveNextAsync();
}
• 名前にAsyncが入ってる
• ジェネリック版のみ
• CancellationTokenをオプションで受け付ける
• 戻り値がValueTask
• Resetメソッドはない
同期版との差
非同期foreach
• IAsyncEnumerable<T>に対するforeach
• 仕組みは同期版とほぼ同じ
• パターンベース
• (同名のメソッドを持って
いればインターフェイス
実装は不要)
await foreach (var x in s)
{
...
}
var e = items.GetAsyncEnumerator();
try
{
while (await e.MoveNextAsync())
{
int item = e.Current;
...
}
}
finally
{
if (e != null) { await e.DisposeAsync(); }
}
• 呼ぶメソッドがAsyncで
• awaitが付く
IAsyncDisposableインターフェイス
• IDisposableの非同期版
public interface IAsyncDisposable
{
ValueTask DisposeAsync();
}
• 名前にAsyncが入ってる
• 戻り値がValueTask
同期版との差
非同期using
• IAsyncDisposableに対するusing
• これも仕組みは同期版とほぼ同じ
• (同期版と違って)
パターンベース
• (同名のメソッドを持って
いればインターフェイス
実装は不要)
await using (d)
{
...
}
try
{
...
}
finally
{
await d.DisposeAsync();
}
• 呼ぶメソッドがAsyncで
• awaitが付く
非同期メソッドの拡張
• 非同期メソッド中にyieldを書けるように
• これまでの非同期メソッド同様、async修飾子を付ける
• これまでのイテレーター同様、メソッド中にyieldを書く
• 戻り値はIAsyncEnumerable<T>である必要あり
async IAsyncEnumerable<int> AsyncIterator()
{
await Task.Delay(1);
yield return 1;
yield break;
}
要するに、非同期メソッド
とイテレーターの混在
補足: (同期)イテレーター
• yield returnの展開結果(疑似コード)
• 状態記録 → 中断 → 再開
_state = State1;
Current = x;
return true;
case State1:
yield return x;
どこまで実行したか記録
IEnumerator<T>.Currentに値をセット
いったん処理を中断
次にIEnumerator<T>.MoveNext
が呼ばれた時の再開場所
補足: await演算子
• awaitの展開結果(疑似コード)
• 状態記録 → 中断 → 再開
_awaiter = task.GetAwaiter();
if (!_awaiter.IsCompleted)
{
_state = State1;
_awaiter.OnComplete(自分自身);
return;
}
case State1:
var result = _awaiter.GetResult();
var result = await task;
どこまで実行したか記録
task完了時に呼びなおしてもらう
いったん処理を中断
OnCompleteが呼ばれた時の再開場所
結果の受け取り
この辺りの構造がyield return
とまったく同じ
非同期イテレーター
• 非同期メソッド中でのyield returnの展開結果(疑似コード)
• 状態記録 → 中断 → 再開 (根底にある仕組みが同じだから混ぜれる)
var result = _awaiter.GetResult();
_state = State1;
Current = result;
_promise.TrySetResult(true);
return;
case State1:
var result = await task;
yield return result;
どこまで実行したか記録
Currentに値をセット
いったん処理を中断
次にMoveNextAsyncが呼ばれた時の再開場所
awaitの結果を受け取り
1つ前のMoveNextAsyncを完了させる
パフォーマンス
• Q. なぜ非同期にしたいか?
• A. パフォーマンスを改善したい
• Taskの生成などのオーバーヘッドがネックになってはいけない
• もしC# 5.0世代の技術でやろうとすると…
interface IAsyncEnumerator<out T>
{
T Current { get; }
Task<bool> MoveNextAsync();
}
_promise = new TaskCompletionSource<T>();
...
_promise.TrySetResult(true);
MoveNextAsyncのたびに
Taskクラスのインスタンスができる
TaskCompletionSourceクラスは
再利用ができないので毎回new
パフォーマンスに関する前提
• 受信側サンプルより再掲:
• 本当に非同期処理が必要なことは少ない
• ReadAllAsyncの方だけ非同期
• Values側は同期
• ReadAllAsyncもバッファリングが効けば同期になることがある
• IAsyncEnumerator<T>.MoveNextAsyncの呼ばれ方
• 1度に1人だけがawaitする
• 戻り値のValueTaskは1回限りGetResultが呼ばれる
await foreach (var res in call.ResponseStream.ReadAllAsync())
foreach (var value in res.Values)
yield return value;
パフォーマンス改善のために
• ValueTask<T>構造体
• C# 7.0/.NET Core 2.0世代
• IValueTaskSource<T>インターフェイス
• C# 7.2/.NET Core 2.1世代
• ManualResetValueTaskSourceCore<T>構造体
• C# 8.0/.NET Core 3.0世代
ちょっと歴史を振り返りつつ説明
Task周りの歴史
Taskクラス初導入から非同期ストリームに至るまで
時系列
2012 2013 2014 2015 2016 2017 2018 2019
Windows 8
WinRT
C# 5.0
Microsoft
CEO交代
Roslyn公開
(オープンソース化)
C# 6.0 C# 7.2 C# 8.0C# 7.0
.NET Framework 4.5 .NET Core 1.1
.NET Core 2.0
.NET Core 2.1
.NET Core 3.0
async/await
ValueTask
IValueTaskSource
ManualResetValueTaskSourceCore
IAsyncEnumerable
Task
一般非同期戻り値 非同期ストリーム
先史時代 (2010年頃)
before “await”
Taskクラス
課題: マルチコア化
• マルチコアCPUの普及
• 高クロック化に限界 (サイズが量子力学的な世界に突入)
• 単体で速くできないので並列に並べるしかない
• コア間のコミュニケーション コストが課題
• 「N個あればN倍」とはならない
• 他のコアの動作を邪魔をしてはいけない
• 暇になっているコアをなくさないといけない
Work stealing
• 小さいタスクを大量にさばくにはスレッドは重たい
• 新規作成・スレッド間のコンテキスト切り替えの負担が大きい
• コア数分のスレッドを事前に立てておく
• 各スレッドにキューを持つ(ローカル キュー)
• タスクは1度キューに詰める
• ローカルでやることがなくなったら他のスレッドのキューからタスク
を奪って(stealing)実行する
• Work stealingって呼ぶ
• 効率のいい実装方法がいろいろ研究されてる
• (JavaとかGoとかでも同時期に)
当時の.NET周り
• Windows 7 (2009/9リリース)
• User Mode Scheduler
• Work stealing的なことをやってる並列処理API
• .NET Framework 4 (2010/4)
• Taskクラス追加
• Parallelクラス追加
• ThreadPoolがWork stealing実装になって効率化
• 当時の課題は「マルチコアを使い切ること」
• CPUをフルに使うような計算主体
Taskクラス(継続呼び出し)
• 同期だと と書けるものがあったとして
• Task以前: Begin/Endのペア
• Task以後: ContinueWith(継続呼び出し)
x.BeginM(state =>
{
var result = x.EndM(state);
});
x.MAsync().ContinueWith(t =>
{
var result = t.Result;
});
var result = x.M();
匿名関数がなかった頃は
もっと大変だった
C# 5.0世代 (2012年頃)
“await”元年
課題: I/O-bound
• CPUの高速化に対して…
• 相対的にストレージ アクセスが遅くなった
• CPUより3・4桁遅い
• ネットワークを使うことが多くなった
• 秒単位で待たされることもざら
• ただ待ってる時間が増える
• 待ち時間にフリーズすると印象が悪い
• 待ってる間に他のことをしたい
• せめて、マウスは動いてほしいし、インジケーターを出したい
I/O-bound
(CPUの外の世界との
入出力がネック)
当時の.NET周り
• Windows 8 (2012/10)
• WinRT (新API)は非同期前提
• 同期処理でフリーズされるくらいなら、いっそ同期APIを用意しない
• I/Oは軒並み非同期APIのみ提供
• .NET Framework 4.5
• 非同期I/OにTaskクラスを使うように
• Stream.ReadAsync, HttpClient.GetAsync, ...
• C# 5.0 (2012/8)
• 非同期メソッド導入
• この当時は戻り値にTaskクラスしか使えなかった
非同期メソッド
• 同期と非同期で同じような書き方ができる
• I/Oを非同期にしたいだけであって、やりたいことは同期と同じ
• やりたいことが同じなら書き方は同じでありたい
void M()
{
var result = x.N();
...
}
async Task MAsync()
{
var result = await x.NAsync();
...
}
同期 非同期
• 非同期処理の前にawaitを付けるだけ
• (習慣上)メソッド名にAsync語尾を付ける
Taskの用途が変わった
• 先史時代: マルチコアをフルに使いたい
• Task.WhenAllやParallel.Forが主力
• await後: むしろI/O待ちに使われるように
• 1つのプログラムでCPUをフルに使いきることはあまりない
• 書きたいコード自体は同期の頃と同じ
• Taskの利用場面の大半がawaitに
余談: C# 5.0→6.0の開発体制
(2012~2015頃)
WindowsからAzureに
オープン化
C# 5.0開発進行上の成約
• WinRTのための非同期メソッド
• Windows 8に合わせてC# 5.0を出すのが必須だった
• Windowsがクローズだったので、C# 5.0もクローズなところがあった
• 非同期メソッドの初期設計もオープンにできないことが多かった
締め切り的にもフィードバック的にもなかなか
自由が利かない中でのawait導入
• 汎用性を持たせる余裕なし
• 戻り値はTask, Task<T>に限る
• awaitはGetAwaiterメソッドを直呼び
C# 6.0開発体制
• MicrosoftのCEO交代で一気にオープンに
• C#コンパイラーも2014/4にオープンソース化(当時はcodeplex)
• 2015/1にGitHub移行
• コンパイラーを1から作り直してたので言語構文的には停滞期
• .NET Coreも1.0は「まずは最低限動く」が目標
• 非同期メソッド周りもいったん据え置き
• 計画としては早期からあった非同期ストリームの話も8.0までおあずけ
• ASP.NET方面からのフィードバックが強くなる
C# 7.0世代 (2017年)
.NET Core 2.0
徐々にパフォーマンス向上が命題に
パフォーマンス
• .NET Core 2.Xはパフォーマンス改善の積み重ねだった
• ガベコレ前提・安全性と生産性優先の言語の中ではだいぶ速くなった
• パフォーマンス的にはC, C++, Rustの次くらいの位置には来れてる
• ヒープ アロケーションをできるかぎり避ける方針に
• ガベコレは十分速いけど、「ヒープを使わない」方がもっと速い
• なので、非同期メソッドのTask<T>のアロケーションも問題に
• ValueTask<T>構造体の導入
• 最初はNuGetパッケージで提供
• .NET Core 2.0から標準提供
ValueTask
• ValueTask<T> = T or Task<T> な共用体
async ValueTask<int> MAsync()
{
if (9割9分) return 1;
await Task.Delay(1);
return 0;
}
高確率で実際には同期処理
低確率で非同期処理
= T を返せばいい
= Task<T> が必要
通信結果をキャッシュしたりバッファリング
したり、こういう場面は結構な頻度で起こる
(高確率でTask<T>のアロケーションを回避)
struct ValueTask<T>
{
T _result;
Task<T> _task;
}
構造
用途の例
非同期メソッド戻り値の汎用化
• C# 7.0で非同期メソッドの戻り値を汎用化
• Task<T>, Task以外の型を非同期メソッドの戻り値にできるように
• パターン ベース(所定のメソッドさえ持っていれば型は問わない)
• ただ、結構複雑なパターンだし、自前で書くことはほとんどない
• なので説明割愛
• 気になる人は「AsyncMethodBuilder」で検索
• (C# 8.0世代ですら)実用上はほぼValueTaskのために入った機能
ValueTaskに掛かるオーバーヘッド
• コスト
• Task<T>とTを両方持つ上に、追加でちょっとフラグを持つ
• (Tによれど大体)16バイト以上になる
• 常に非同期な場合は単なるオーバーヘッド
• 結局Task<T>クラスが作られた上で大きめの構造体コピーが発生
C# 7.0世代での問題
後に出てくる改善案が
IValueTaskSource<T>
C# 7.2世代 (2018年)
.NET Core 2.1
本格的にパフォーマンス向上が命題に
非同期戻り値を汎用化するにあたって
• おさらい
• Task/Task<T>のアロケーションを避けたい
• await用途の場合いくつか前提を置ける
• 1度に1人だけがawaitする
• 1回限りGetResultが呼ばれる
• AsyncMethodBuilderを作るのはそれなりに大変
• 結局、ValueTaskに乗っかりたい
• IValueTaskSouceインターフェイスを提供することに
IValueTaskSource<T>
• 非同期メソッドの戻り値の求められる要件を満たす型
• ValueTask<T>の仕組みに乗っかれる
• ValueTask<T>のコンストラクターに渡せる
• AsyncMethodBuilderはValueTask<T>のものをそのまま使う
public interface IValueTaskSource<out TResult>
{
ValueTaskSourceStatus GetStatus(short token);
void OnCompleted(Action<object?> continuation, object? state,
short token, ValueTaskSourceOnCompletedFlags flags);
TResult GetResult(short token);
}
IValueTaskSource<T>
• やりたいこと自体はTask<T>と同じ
public interface IValueTaskSource<out TResult>
{
ValueTaskSourceStatus GetStatus(short token);
void OnCompleted(Action<object?> continuation, object? state,
short token, ValueTaskSourceOnCompletedFlags flags);
TResult GetResult(short token);
}
public class Task<TResult>
{
TaskStatus Status { get; }
Task ContinueWith(Action<Task> continuation);
TResult Result { get; }
}
≒
IValueTaskSource<T>
• パフォーマンスへの配慮あり
public interface IValueTaskSource<out TResult>
{
ValueTaskSourceStatus GetStatus(short token);
void OnCompleted(Action<object?> continuation, object? state,
short token, ValueTaskSourceOnCompletedFlags flags);
TResult GetResult(short token);
}
• 何回目の呼び出しかを弁別するための数値
• 1つのインスタンスを使いまわす前提
アロケーションを少しでも減らす
ValueTask<T>側の変化
• ValueTask<T> = T or Task<T> or IValueTaskSource<T>
struct ValueTask<T>
{
T _value;
object _task;
short _token;
}
is演算子でTask<T> or IValueTaskSource<T>に分岐
何回目の呼び出しかを弁別するための数値
最初から完了しているときはTを直接渡す
ValueTask/IValueTaskSource (型引数なし)
• ValueTask = Task or IValueTaskSource or 完了済み
struct ValueTask
{
object _task;
short _token;
}
is演算子でTask or IValueTaskSourceに分岐
nullだったら完了済み
何回目の呼び出しかを弁別するための数値
public interface IValueTaskSource
{
ValueTaskSourceStatus GetStatus(short token);
void OnCompleted(Action<object?> continuation, object? state,
short token, ValueTaskSourceOnCompletedFlags flags);
void GetResult(short token);
}
IValueTaskSourceを再利用
• インスタンスの再利用でアロケーションを減らす例
• 1つのインスタンス(_sourceに格納)を使いまわす
• 1つ前のM()呼び出しが終わる前に重複でM()を呼ばない
• ResetのたびにTokenを変える
• TrySetResult時にTokenが不一致だと例外を出す
ValueTaskSource _source = new ValueTaskSource();
ValueTask M()
{
_source.Reset();
return new ValueTask(_source, _source.Token);
}
どこか別の場所でTrySetResultする
TaskよりValueTaskの方が汎用的に
• Task … 具象クラス。あまり変更の余地なし
• ValueTask … これ自体は変更の余地なし
• IValueTaskSrouceを渡せる
• IValueTaskSrouceは自由に実装できる
• どちらが推奨か
interface X
{
Task M1();
ValueTask M2();
}
インターフェイスみたいに
実装がどうなるかわからないとき、
TaskにすべきかValueTaskにすべきか
TaskよりValueTaskの方が汎用的に
• Task … 具象クラス。あまり変更の余地なし
• ValueTask … これ自体は変更の余地なし
• IValueTaskSrouceを渡せる
• IValueTaskSrouceは自由に実装できる
• どちらが推奨か
• 昔: ValueTaskにもコストはあるし、構造体は扱いにくいし
• Task優位
• 今: ValueTaskの方が汎用になったし、実装次第では高パフォーマンス
• ValueTask優位
ただし、構造体の扱いにくさは残ってる…
扱いにくさ
• 後入りなので…
• Task戻り値をValueTask戻り値に変えると破壊的変更になる
• TaskとValueTaskが混在しているときにWhenAnyとかが面倒
• 構造体なので…
• box化に気を付けないといけない
• ValueTask<T>とValueTaskに継承関係がない
• それぞれに対して同じロジックを多重保守する必要あり
• 組み合わせ爆発もあり得る
void M(ValueTask a, ValueTask b);
void M<T>(ValueTask a, ValueTask<T> b);
void M<T>(ValueTask<T> a, ValueTask b);
void M<T>(ValueTask<T> a, ValueTask<T> b);
引数の数nに対して
2 𝑛個のオーバーロード
C# 8.0世代(2019年)
IValueTaskSourceが本腰
非同期ストリーム
IValueTaskSourceってどう実装するの?
• IValueTaskSourceを使えと言われましても…
• 汎用にできるといってもやることはほぼ常に同じ
• スレッド安全でないとダメ
• ちゃんと書くのは結構難しい
• 共通処理を詰め込んだ構造体を提供
• ManualResetValueTaskSourceCore<T>
• 自前のクラスにこの構造体のフィールドを持たせて、
IValueTaskSourceの実装に使える
ManualResetValueTaskSourceCoreの例
• IValueTaskSource<T>の処理をほぼ丸投げ
class ValueTaskSource : IValueTaskSource<T>
{
private ManualResetValueTaskSourceCore<T> _core;
public int GetResult(short token) => _core.GetResult(token);
public ValueTaskSourceStatus GetStatus(short token) => _core.GetStatus(token);
public void OnCompleted(Action<object> continuation, object state, short token, ...)
=> _core.OnCompleted(continuation, state, token, flags);
public ValueTask<T> ValueTask => new ValueTask<T>(this, _core.Version);
}
フィールドに持って
ほぼ丸投げ
Reset(再利用)とかTrySetResult(完了)とかの
タイミングだけ独自にコントロールしてやればOK
非同期ストリームの中身
• ManualResetValueTaskSourceCore<T>を使って実装
await foreach (var x in s)
{
...
}
while (await e.MoveNextAsync())
{
int item = e.Current;
...
var result = _awaiter.GetResult();
_state = State1;
Current = result;
_promise.TrySetResult(true);
return;
case State1:
var result = await task;
yield return result;
再掲・抜粋
戻り値がValueTask<T>
本当に非同期な時だけアロケーション
ManualResetValueTaskSourceCore<T>を利用
何度MoveNextAsyncを呼んでも同じインスタンスを使いまわし
1度に1人だけがawaitする想定
• continuation (OnCompleteで呼ぶ処理)の管理がシンプルに
(=高速)
• 複数いると…
• List<Action>なフィールドを持って
• lockを書けてAdd/Remove
• 1度に1人だけだと
• Actionなフィールドを持って
• CompareExchangeで入れ替えするだけ
List自体のnewが発生
lockと比べると軽い処理
ManualResetValueTaskSourceCore<T>
はこっちを採用
「1度に1人だけ」想定
• 普通は書かないようなコードを書くと例外が出る
async IAsyncEnumerable<int> A()
{
await Task.Delay(10); yield return 1;
await Task.Delay(10); yield return 2;
}
async Task B()
{
var a = A();
var e = a.GetAsyncEnumerator();
var t1 = e.MoveNextAsync();
var t2 = e.MoveNextAsync(); // t1 完了前に次の MoveNextAsync を呼ぶ
await t1; // ここで例外が起こる
}
パフォーマンスとの引き換えで
意図的にそういう仕様
まとめ
• 非同期で複数のデータを受け渡し
• C# 8.0の新機能
• 非同期メソッドの拡張 : awaitとyieldの混在
• 非同期foreach : await foreach (var x in asyncStream)
• パフォーマンスへの配慮
• ValueTask
• 本当に非同期の時だけアロケーション
• IValueTaskSource/ManualResetValueTaskSourceCore
• 「1度に1人だけawait」な前提で最適化

More Related Content

What's hot

C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングKohsuke Yuasa
 
MagicOnion入門
MagicOnion入門MagicOnion入門
MagicOnion入門torisoup
 
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところY Watanabe
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較Akihiro Suda
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法についてYuji Otani
 
Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話torisoup
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪Takuto Wada
 
こわくない Git
こわくない Gitこわくない Git
こわくない GitKota Saito
 
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」U-dai Yokoyama
 
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~ CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~ SEGADevTech
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているKoichi Tanaka
 
クラウド環境下におけるAPIリトライ設計
クラウド環境下におけるAPIリトライ設計クラウド環境下におけるAPIリトライ設計
クラウド環境下におけるAPIリトライ設計Kouji YAMADA
 
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてカスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてalwei
 
C++の話(本当にあった怖い話)
C++の話(本当にあった怖い話)C++の話(本当にあった怖い話)
C++の話(本当にあった怖い話)Yuki Tamura
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpsonickun
 
Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Etsuji Nakai
 
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptxネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptxShota Shinogi
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)Akihiko Matuura
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなKentaro Matsui
 

What's hot (20)

C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
 
MagicOnion入門
MagicOnion入門MagicOnion入門
MagicOnion入門
 
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
こわくない Git
こわくない Gitこわくない Git
こわくない Git
 
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
 
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~ CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っている
 
クラウド環境下におけるAPIリトライ設計
クラウド環境下におけるAPIリトライ設計クラウド環境下におけるAPIリトライ設計
クラウド環境下におけるAPIリトライ設計
 
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてカスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
 
C++の話(本当にあった怖い話)
C++の話(本当にあった怖い話)C++の話(本当にあった怖い話)
C++の話(本当にあった怖い話)
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjp
 
Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門
 
C#で速度を極めるいろは
C#で速度を極めるいろはC#で速度を極めるいろは
C#で速度を極めるいろは
 
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptxネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
 

Similar to C# 8.0 非同期ストリーム

C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)信之 岩永
 
WASM(WebAssembly)入門 ペアリング演算やってみた
WASM(WebAssembly)入門 ペアリング演算やってみたWASM(WebAssembly)入門 ペアリング演算やってみた
WASM(WebAssembly)入門 ペアリング演算やってみたMITSUNARI Shigeo
 
TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~Akira Inoue
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#信之 岩永
 
Dotnetcore30forwindesktop
Dotnetcore30forwindesktopDotnetcore30forwindesktop
Dotnetcore30forwindesktopru pic
 
Visual Studio 2012 Web 開発 ~ One ASP.NET から TypeScript まで ~
Visual Studio 2012 Web 開発 ~ One ASP.NET から TypeScript まで ~Visual Studio 2012 Web 開発 ~ One ASP.NET から TypeScript まで ~
Visual Studio 2012 Web 開発 ~ One ASP.NET から TypeScript まで ~Akira Inoue
 
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~Akira Inoue
 
TypeScriptへの入口
TypeScriptへの入口TypeScriptへの入口
TypeScriptへの入口Sunao Tomita
 
Visual Studioで始めるTypeScript開発入門
Visual Studioで始めるTypeScript開発入門Visual Studioで始めるTypeScript開発入門
Visual Studioで始めるTypeScript開発入門Narami Kiyokura
 
TypeScript ファースト ステップ (v.0.9 対応版) ~ Any browser. Any host. Any OS. Open Sourc...
TypeScript ファースト ステップ (v.0.9 対応版) ~ Any browser. Any host. Any OS. Open Sourc...TypeScript ファースト ステップ (v.0.9 対応版) ~ Any browser. Any host. Any OS. Open Sourc...
TypeScript ファースト ステップ (v.0.9 対応版) ~ Any browser. Any host. Any OS. Open Sourc...Akira Inoue
 
パターンでわかる! .NET Coreの非同期処理
パターンでわかる! .NET Coreの非同期処理パターンでわかる! .NET Coreの非同期処理
パターンでわかる! .NET Coreの非同期処理Kouji Matsui
 
.NET Core とマルチプラットフォーム
.NET Core とマルチプラットフォーム.NET Core とマルチプラットフォーム
.NET Core とマルチプラットフォームshozon
 
DEV-002_.NET Core/ASP.NET Core が実現するクロスプラットフォーム .NET の今と未来
DEV-002_.NET Core/ASP.NET Core が実現するクロスプラットフォーム .NET の今と未来DEV-002_.NET Core/ASP.NET Core が実現するクロスプラットフォーム .NET の今と未来
DEV-002_.NET Core/ASP.NET Core が実現するクロスプラットフォーム .NET の今と未来decode2016
 
Windows 8時代のアプリ開発
Windows 8時代のアプリ開発Windows 8時代のアプリ開発
Windows 8時代のアプリ開発信之 岩永
 
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説Akira Inoue
 
ASP.NET vNextの全貌
ASP.NET vNextの全貌ASP.NET vNextの全貌
ASP.NET vNextの全貌A AOKI
 

Similar to C# 8.0 非同期ストリーム (20)

C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)
 
WASM(WebAssembly)入門 ペアリング演算やってみた
WASM(WebAssembly)入門 ペアリング演算やってみたWASM(WebAssembly)入門 ペアリング演算やってみた
WASM(WebAssembly)入門 ペアリング演算やってみた
 
TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
 
Dotnetcore30forwindesktop
Dotnetcore30forwindesktopDotnetcore30forwindesktop
Dotnetcore30forwindesktop
 
Visual Studio 2012 Web 開発 ~ One ASP.NET から TypeScript まで ~
Visual Studio 2012 Web 開発 ~ One ASP.NET から TypeScript まで ~Visual Studio 2012 Web 開発 ~ One ASP.NET から TypeScript まで ~
Visual Studio 2012 Web 開発 ~ One ASP.NET から TypeScript まで ~
 
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
 
20010901
2001090120010901
20010901
 
20201127 .NET 5
20201127 .NET 520201127 .NET 5
20201127 .NET 5
 
TypeScriptへの入口
TypeScriptへの入口TypeScriptへの入口
TypeScriptへの入口
 
Visual Studioで始めるTypeScript開発入門
Visual Studioで始めるTypeScript開発入門Visual Studioで始めるTypeScript開発入門
Visual Studioで始めるTypeScript開発入門
 
TypeScript ファースト ステップ (v.0.9 対応版) ~ Any browser. Any host. Any OS. Open Sourc...
TypeScript ファースト ステップ (v.0.9 対応版) ~ Any browser. Any host. Any OS. Open Sourc...TypeScript ファースト ステップ (v.0.9 対応版) ~ Any browser. Any host. Any OS. Open Sourc...
TypeScript ファースト ステップ (v.0.9 対応版) ~ Any browser. Any host. Any OS. Open Sourc...
 
パターンでわかる! .NET Coreの非同期処理
パターンでわかる! .NET Coreの非同期処理パターンでわかる! .NET Coreの非同期処理
パターンでわかる! .NET Coreの非同期処理
 
.NET Core とマルチプラットフォーム
.NET Core とマルチプラットフォーム.NET Core とマルチプラットフォーム
.NET Core とマルチプラットフォーム
 
.NET vNext
.NET vNext.NET vNext
.NET vNext
 
【BS2】.NET 6 最新アップデート
【BS2】.NET 6 最新アップデート【BS2】.NET 6 最新アップデート
【BS2】.NET 6 最新アップデート
 
DEV-002_.NET Core/ASP.NET Core が実現するクロスプラットフォーム .NET の今と未来
DEV-002_.NET Core/ASP.NET Core が実現するクロスプラットフォーム .NET の今と未来DEV-002_.NET Core/ASP.NET Core が実現するクロスプラットフォーム .NET の今と未来
DEV-002_.NET Core/ASP.NET Core が実現するクロスプラットフォーム .NET の今と未来
 
Windows 8時代のアプリ開発
Windows 8時代のアプリ開発Windows 8時代のアプリ開発
Windows 8時代のアプリ開発
 
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
 
ASP.NET vNextの全貌
ASP.NET vNextの全貌ASP.NET vNextの全貌
ASP.NET vNextの全貌
 

More from 信之 岩永

YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話信之 岩永
 
C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話信之 岩永
 
Unicode文字列処理
Unicode文字列処理Unicode文字列処理
Unicode文字列処理信之 岩永
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型信之 岩永
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ信之 岩永
 
C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1信之 岩永
 
C#言語機能の作り方
C#言語機能の作り方C#言語機能の作り方
C#言語機能の作り方信之 岩永
 
Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6信之 岩永
 
それっぽく、適当に
それっぽく、適当にそれっぽく、適当に
それっぽく、適当に信之 岩永
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform信之 岩永
 
Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3信之 岩永
 
Code Contracts in .NET 4
Code Contracts in .NET 4Code Contracts in .NET 4
Code Contracts in .NET 4信之 岩永
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略信之 岩永
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略信之 岩永
 
C# design note sep 2014
C# design note sep 2014C# design note sep 2014
C# design note sep 2014信之 岩永
 
C#/.NETがやっていること 第二版
C#/.NETがやっていること 第二版C#/.NETがやっていること 第二版
C#/.NETがやっていること 第二版信之 岩永
 

More from 信之 岩永 (20)

YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話
 
C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0
 
C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話
 
Unicode文字列処理
Unicode文字列処理Unicode文字列処理
Unicode文字列処理
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
 
C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1
 
C#言語機能の作り方
C#言語機能の作り方C#言語機能の作り方
C#言語機能の作り方
 
Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6
 
それっぽく、適当に
それっぽく、適当にそれっぽく、適当に
それっぽく、適当に
 
Modern .NET
Modern .NETModern .NET
Modern .NET
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform
 
Deep Dive C# 6.0
Deep Dive C# 6.0Deep Dive C# 6.0
Deep Dive C# 6.0
 
Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3
 
Code Contracts in .NET 4
Code Contracts in .NET 4Code Contracts in .NET 4
Code Contracts in .NET 4
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略
 
C# design note sep 2014
C# design note sep 2014C# design note sep 2014
C# design note sep 2014
 
C#/.NETがやっていること 第二版
C#/.NETがやっていること 第二版C#/.NETがやっていること 第二版
C#/.NETがやっていること 第二版
 
Coding Interview
Coding InterviewCoding Interview
Coding Interview
 

Recently uploaded

Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 

Recently uploaded (8)

Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 

C# 8.0 非同期ストリーム

Editor's Notes

  1. これまでもgRPCのツールにproto定義を食わせればコード生成されてた。 VS 16.3で、コード生成がVisual Studioに組み込まれて、protoの保存と同時にC#コードが生成されるようになった。
  2. この辺りが、計画上はC# 5.0時代からあったけど、実際に実装されたのがC# 8.0世代になった理由。
  3. JavaでもJava 7 (2011//7)にForkJoinPoolっていう型追加 Go (2012/3)のgoroutineもWork stealingで実装されてる
  4. 今時のCPU/GPUは、G flops とか T flops とかな単位の計算能力がある。 「秒単位で待たされる」ってのは、Giga(9桁)とかTera(12桁)とかの命令処理能力を無駄にするってことに。
  5. ちなみに、非同期I/O用のOS機能はWindowsだとI/O Completion Port、Linuxだとepoll、BSD/Macだとkqueue
  6. それはそれで、variance効かないとかValueTask<T>がValuTask派生じゃないとか、いろいろ使いにくくはある object/interfaceに渡すとbox化する問題もあるし。TaskとValueTaskの混在がめんどいとか、WhenAnyしにくいとかの問題もあり