.NET响应式编程扩展

       LINQ是一种拉取模式,在查询过程中数据项是被逐个拉取出来的。例如有IEnumerable<string>提供给我们字符串值。当迭代它时,并不知道每个迭代会花费多长时间。如果使用常规的foreach或其他的同步迭代构造方式,我们将阻塞线程直到得到下一个值,这可能导致整个处理非常慢。这种场景被称为“基于拉取”的方式。基于推送的方式即生产者通知客户端有新值要处理。这将把工作推给生产者,而客户端在等待另一个值的时候可以做其他事情。因此目标是实现类似于IEnumerable的异步版本的一个机制,可以生产一组序列值并按顺序通知消费者处理这些值,直到序列处理完成或抛出异常。
      Reactive Extensions(Rx)把事件看作是依次到达的数据序列。因此,将Rx认作是LINQ to events(基于IObservable<T>)也是可以的,它与其他LINQ提供者的主要区别在于,Rx采用“推送”模式,就是说,Rx的查询规定了在事件到达时程序该如何响应。Rx在LINQ的基础上构建,增加了一些功能强大的操作符作为扩展方法。
     IObservable和IObserver它们一起代表了异步的基于推送的集合及其客户端。 Rx的观察者+迭代器模式 Rx中含有两个基本概念:Observable与Observer。Observables作为被观察者,是一个值或事件的流集合;而 Observer则作为观察者,根据Observables进行处理。Observables与Observer之间的订阅发布关系(观察者模式)如下:订阅:Observer 通过 Observable 提供的 subscribe() 方法订阅 Observable。发布:Observable 通过回调 Next方法向Observer发布事件。

(一)将普通集合转换为异步可观察的集合

static void Main(string[] args) { foreach (int i in EnumerableEventSequence()) { Console.WriteLine($"IEnumerable【{i}】:{DateTime.Now.ToString("HH:mm:ss.fff")}"); } Console.WriteLine($"=====【{DateTime.Now.ToString("HH: mm:ss.fff")}】IEnumerable 方式迭代完成"); IObservable<int> o = EnumerableEventSequence().ToObservable(); using (IDisposable subscription = o.Subscribe((i) => { Console.WriteLine($"IObservable【{i}】:{DateTime.Now.ToString("HH:mm:ss.fff")}"); })) { Console.WriteLine($"=====【{DateTime.Now.ToString("HH: mm:ss.fff")}】IObservable 方式迭代完成"); } o = EnumerableEventSequence().ToObservable().SubscribeOn(TaskPoolScheduler.Default); using (IDisposable subscription = o.Subscribe((i) => { Console.WriteLine($"IObservable async【{i}】:{DateTime.Now.ToString("HH:mm:ss.fff")}"); })) { Console.WriteLine($"=====【{DateTime.Now.ToString("HH: mm:ss.fff")}】IObservable async 方式迭代完成"); //此处与迭代并行执行 Console.ReadLine(); } Console.WriteLine("Hello World!"); Console.ReadLine(); } static IEnumerable<int> EnumerableEventSequence() { for (int i = 0; i < 10; i++) { Thread.Sleep(TimeSpan.FromSeconds(1)); yield return i; } }

image

(二).NET 事件转换

var timer = new System.Timers.Timer(interval: 1000) { Enabled = true };
var ticks = Observable.FromEventPattern(timer, "Elapsed");
ticks.Subscribe(data => Trace.WriteLine($"OnNext:{((ElapsedEventArgs)data.EventArgs).SignalTime}"));
posted @ 2022-02-16 09:31  李华丽  阅读(123)  评论(1编辑  收藏  举报
AmazingCounters.com