TPL vs Reactive Framework

后端 未结 5 1124
礼貌的吻别
礼貌的吻别 2020-12-13 12:39

When would one choose to use Rx over TPL or are the 2 frameworks orthogonal?

From what I understand Rx is primarily intended to provide an abstraction over events an

5条回答
  •  南笙
    南笙 (楼主)
    2020-12-13 13:01

    Update, December 2016: If you have 30 minutes, I recommend you read Joe Duffy's first-hand account instead of my speculation. I think my analysis holds up well, but if you've found this question I highly recommend you see the blog post instead of these answers because in addition to TPL vs Rx.NET he also covers MS research projects (Midori, Cosmos).

    http://joeduffyblog.com/2016/11/30/15-years-of-concurrency/


    I think MS made a big mistake over-correcting after .NET 2.0 came out. They introduced many different concurrency management APIs all at the same time from different parts of the company.

    • Steven Toub was pushing hard for thread-safe primitives to replace Event (which started as Future and turned into Task)
    • MS Research had MIN-LINQ and Reactive Extensions (Rx)
    • Hardware/Embedded had robotics cuntime (CCR)

    In the meantime many managed API teams were trying to live with APM and Threadpool.QueueUserWorkItem(), not knowing if Toub would win his fight to ship Future/Task in mscorlib.dll. In the end it looks like they hedged, and shipped both Task and IObservable in mscorlib, but didn't allow any other Rx APIs (not even ISubject) in mscorlib. I think this hedge ended up causing a huge amount of duplication (more later) and wasted effort inside and outside the company.

    For duplication see: Task vs. IObservable, Task vs. AsyncSubject, Task.Run() vs. Observable.Start(). And this is just the tip of the iceberg. But at a higher level consider:

    • StreamInsight - SQL event streams, native-code-optimized, but event queries defined using LINQ syntax
    • TPL Dataflow - built on TPL, built in parallel to Rx, optimized for tweaking threading parallelism, not good at composing queries
    • Rx - Amazing expressiveness, but fraught with peril. Mixes 'hot' streams with IEnumerable-style extension methods, which means you very easily block forever (calling First() on a hot stream never returns). Scheduling limits (limiting parallelism) is done via rather odd SubscribeOn() extension methods, which are weirdly implicit and hard to get right. If starting to learn Rx reserve a long time to learn all the pitfalls to avoid. But Rx is really the only option if composing complex event streams or you need complex filtering/querying.

    I don't think Rx has a fighting chance at wide adoption until MS ships ISubject in mscorlib. Which is sad, because Rx contains some very useful concrete (generic) types, like TimeInterval and Timestamped, which I think should be in Core/mscorlib like Nullable. Also, System.Reactive.EventPattern.

提交回复
热议问题