除了 Paul 的出色回答,我还想添加拉取数据与推送数据的概念。
管道
让我们以一些生成一系列数字并输出结果的代码为例。如果您将其视为一端的流,则您有一个producer正在为您创建新数字的流,而在另一端您有一个consumer正在对这些数字进行操作的流。
拉 - 素数列表
可以说producer正在生成一个素数列表。通常你会有一些函数产生一个数字列表,每次它返回时,它都会通过管道将它计算的下一个值推送到consumer,这会将那个数字输出到屏幕上。
Prime 生成器 ---> Console.WriteLine
在这种情况下,很容易看出producer正在做大部分工作,并且consumer会坐等producer发送下一个值。consumer正在拉动管道,等待producer返回下一个值。
Push - 来自快速进程的进度百分比事件(反应式)
好的,假设您有一个处理 1,000,000 个项目的函数。每个项目需要几毫秒的时间来处理,然后该函数会产生一个百分比值,表示它已经走了多远。如此多的进度值,非常快。
在管道的另一端,您有一个进度条。现在,如果进度条要处理每次更新,UI 将阻止尝试跟上值流。
100 万个项目处理器 ---> 进度条
在这种情况下,数据被推送通过管道,producer然后被阻塞,因为推送consumer了太多数据以使其无法处理。
Reactive 允许您根据您希望consume数据的方式设置延迟、窗口或对管道进行采样。在这种情况下,我会在更新进度条之前每秒对数据进行一次采样。
列表与事件
所以列表和事件有点相同。区别在于数据是通过系统拉取还是推送。使用列表来提取数据。使用事件推送数据。