c# unirx プッシュベースとプルベースの構造(IEnumerable<T>およびIObservable<T>



rx subscribe (4)

IEnumerableIObservableについて、 IEnumerableプルベースの構造であり、 IObservableはプッシュベースの構造です。

私はIObservableでそれを読んだことがあります。非同期呼び出しがあり、何もブロックされず 、すべてがプッシュベースです。

しかし、しかし、しかし...

それは本当に何を意味しますか? プッシュベースとプルベース

私の考えではIEnumerableでは構造体にデータをプッシュすることもできますし、そこからデータを引き出すこともできます。私はその技術的な用語やアイディアを失ってしまいました。

プッシュベースとプルベースの2つの構造との違いを私に説明してください。

ありがとう。


Answer #1

男は食料雑貨店に入り、店主に卵があるかどうか尋ねる。 店主は「はい、」と言っています。 "私はいくつか持っていてもいいですか?" その男に尋ねる。 店主は男に卵を渡します。 "あなたはもうこれ以上持っていますか?" その男に尋ねる。 店主は「はい、」と言っています。 "私はいくつか持っていてもいいですか?" その男に尋ねる。 店主は男に卵を渡します。 "あなたはもうこれ以上持っていますか?" その男に尋ねる。 店主は言う。 "いいえ。 男は去る。

それはプルベースです。 男は店主から卵を引き抜いて残さないようにしています。

ある男性が食料品店に入り、店主に卵を配達できるかどうかを尋ね、もしそうなら、いつでも彼が卵を手に入れることができる。 店主は「はい、」と言っています。 男は去る。 数日のうちにいくつかの卵が到着します。 数日後にいくつかの卵が到着します。 そして、その男は店主に電話をかけ、配送が止まるように頼む。 もう卵は到着しません。

プッシュベースです 男は店主が彼に卵を与えるのを待っていない。 男は何か他のことをすることに行き、店主は卵を男性に "押し込む"。


Answer #2

上記の大きな回答に加えて、私はまた以下を提供するでしょう:

  • 'enumerable'を意味する 'IEnumerable'は、.NETフレームワークの概念モデルで 'pull based'と暗黙のうちに混同されています。 これは、 "あなたが次の値を引き出すことを可能にする列挙子を得ることを可能にする"ことを意味することを意図している
  • しかし、IAsyncEnumerableもあります。
  • 数学的に、列挙可能なものは単に「可算」を意味する。
  • オブザーバブルは、独立したイベントの集合を表す可能性があるという意味で、数えることもできる。

命名は混乱していると私の意見では、彼らが意図している概念をうまく表現していません。 たとえば、Javaの世界では、IEnumerableはIterableであり、これは.NETの意図に近いものです。

私は、IEnumerableとLINQが"いくつかのソースからいくつかのデータを取得し、このようなグループ化/グループ化..."というように IEnumerableとLINQを構築するのが最も簡単だと思いますオブザーバブルは、反応できる入力ストリームと考えることができます。 私は、オブザーバブルを継続と考えるのは必ずしも役立たないと思います。


Answer #3

私と人間の違いを説明してください

OK、トーストを作ってみましょう。 それは私がやっている人間の最も普通のことです。

プルベース:

// I want some toast.  I will pull it out of the toaster when it is done.
// I will do nothing until the toast is available.
Toast t = toaster.MakeToast();
t.AddJam();
// Yum.

プッシュベース:

// I want some toast.  But it might take a while and I can do more work
// while I am waiting:
Task<Toast> task = toaster.MakeToastAsync();
Toast t = await task;
// await returns to the caller if the toast is not ready, and assigns
// a callback. When the toast is ready, the callback causes this method
// to start again from this point:
t.AddJam();
// Yum.

結果を取得したい場合は、関数を呼び出し、関数が返るまで何もしないでください。

あなたは結果をあなたにプッシュしたい、あなたは非同期関数を呼び出して結果を待つ。 結果が利用可能になるとコールバックにプッシュされ、コールバックが必要なメソッドを再開します。

IEnumerable<T>はプルのシーケンスです。 結果をプルするたびにMoveNextを呼び出し、 Tを取得します。 IObservable<T>はプッシュのシーケンスです。 コールバックを登録し、新しいTが利用可能になるたびに呼び出されます。

IEnumerable<T>は論理的にFunc<T> 呼び出しのシーケンスです。 IObservable<T>は、論理的にはTask<T> 継続のシーケンスです。 それらがシーケンスであるという事実をあなたに混乱させないでください。 それは偶然です。 基本的な考え方は、関数は同期的であるということです。 あなたはそれらを呼び出して、 同期して結果を得る。 しばらく時間がかかると、あなたは待っています。 タスクは非同期です。 それらを起動し、使用可能なときに非同期で結果を取得します。

このアイデアはIObservable前にC#で存在し、 awaitます。 これを見るもう1つの方法は、プル型は関数呼び出し、プッシュ型はイベントハンドラと似ています。 通常の関数呼び出しで、何かが必要なときに呼び出します。 イベントハンドラで、何かが起きたときにあなたを呼び出します。 イベントは、C#言語自体がオブザーバパターンをどのように表現するかです。 しかし、イベントは常に論理的にシーケンスを形成するので、プルされたアイテムのシーケンスを操作するのと同じ方法で、プッシュされたアイテムのシーケンスを操作できることは理にかなっています。 したがって、 IObservableが発明されました。


Answer #4

データがいつ配信されるのかを決定する(論理的な)サーバーとクライアント、サーバーまたはクライアントを想定していますか?

プルベースは、クライアントが実行する方式を表します。クライアントは要求を行い、データはすぐに処理されます。 プッシュベースとは、プッシュストリーム(IObservable)に接続することができますが、データを要求することはできません。サーバーは、プッシュストリームを提供すると感じるとそのデータを取得します。

正式なプルはデータベースクエリです。サーバーに要求を送信すると、サーバーはアイテムの集合で応答します。 正式版のプッシュはチャットアプリになります。チャットクライアントは新しい会話データを「要求」することはできません。他の人が何か言ったときにサーバーから通知されます。





ienumerable