About reactive Extensions (Rx)
for reactive Extensions (Rx), let's take a look at the official description from Microsoft:
The reactive Extensions (Rx) is a library for composing asynchronous and event-based programs using observable sequences a nd linq-style query operators. Using Rx, developers represent asynchronous data streams with observables, query asynchronous Data Strea Ms using LINQ operators, and parameterize the concurrency in the asynchronous data streams using schedulers. Simply put, Rx = observables + LINQ + schedulers.
The reactive Extensions (RX) is a class library that integrates asynchronous, observable (observable) sequence-based event-driven programming and Linq-style query operations. With RX, developers can use observable objects to describe asynchronous data flows, use LINQ operators to query data asynchronously, and use schedulers to control concurrency in asynchronous processes. In short, Rx = observables + LINQ + schedulers. ”
Reactive Extensions (RX) must be multithreaded?
In the above description, there is a recurring word "async". In general, the mention of "async", the first response is multithreading. The question comes, using reactive extensions must mean multithreading? Let's look at an example, where the code comes in:
1 Static voidMain (string[] args)2 {3Console.WriteLine ("starting on threadid:{0}", Thread.CurrentThread.ManagedThreadId);4 varSub =NewSubject<object>();5 6Sub. Subscribe (o = Console.WriteLine ("Received {1} on threadid:{0}",//for observable subscription processor (handler), output handler thread ID7 Thread.CurrentThread.ManagedThreadId,8 o));9Parameterizedthreadstart notify = obj =//delegate definition, which outputs the thread ID of the observed objectTen { OneConsole.WriteLine ("OnNext ({1}) on threadid:{0}", A Thread.CurrentThread.ManagedThreadId, - obj); - Sub. OnNext (obj); the }; -Notify1); - NewThread (notify). Start (2); - NewThread (notify). Start (3); + - Console.read (); +}
In the code, the thread ID of the notifier and the thread ID of the callback handler are output separately. This is used by the RX default thread concurrency mode. The output results are as follows:
Both the notifier and the processing method are on the same thread, either at the current thread invocation or city threads execution. In this example, the thread assignment of Rx is working in free-threaded mode, and free-threaded means that we do not forcibly refer to the subscription in its RX, notification the thread of execution. This is the default operating mode for Rx, and in this mode Subscribing/call OnNext does not raise a new thread to process the observable sequence, the line is single-threaded (onethreaded Apartment, STA). So, we can say this: single-threaded is the default way to handle reactive Extensions (Rx).
Use Subscribeon to control the context of a subscription (subscribing)
The iobservable<tsource> extension method subscribeon<tsource> (IScheduler) allows us to pass in a scheduler (Scheduler) to control the context of the subscription execution.
1 Static voidMain (string[] args)2 {3Console.WriteLine ("starting on threadid:{0}", Thread.CurrentThread.ManagedThreadId);4 varSource = observable.create<int>(5o =6 {7Console.WriteLine ("invoked on threadid:{0}", Thread.CurrentThread.ManagedThreadId);8O.onnext (1);9O.onnext (2);TenO.onnext (3); One o.oncompleted (); AConsole.WriteLine ("finished on threadid:{0}", - Thread.CurrentThread.ManagedThreadId); - returnDisposable.empty; the }); - Source - //. Subscribeon (Scheduler.threadpool) - . Subscribe ( +o = Console.WriteLine ("Received {1} on threadid:{0}", - Thread.CurrentThread.ManagedThreadId, + o), A() = Console.WriteLine ("oncompleted on threadid:{0}", at Thread.CurrentThread.ManagedThreadId)); -Console.WriteLine ("subscribed on threadid:{0}", Thread.CurrentThread.ManagedThreadId); - - Console.read (); -}
Code, create a observable sequence using observable.create, and then subscribe to the sequence. The output is:
When the sequence is subscribed to the source. Subscribe, the proxy observable.create is invoked to execute. The first is OnNext (1) handler, which in turn is OnNext (2) OnNext (3) handler and oncompleted handler, and finally executes to "subscribed on Threadid:10". The whole process is linear, blocking (block)-type. This is in accordance with the above analysis of the RX default single thread mode.
Let's go. Subscribeon (Scheduler.threadpool), specifies that the RX work is done in the thread pool. The results of the implementation are as follows:
As you can see, all the handler are done within a new thread. This is a non-blocking (no=-block) mode.
The Subscribeon method is commonly used to specify the thread execution mode for observable notifications (where execution is performed). It is commonly used in the following scenarios:
"UI thread does not allow blocking
"Does not need to update the display in the UI thread
Common Scheduler Properties:
CurrentThread |
Dispatch work as soon as possible in the current process, synchronization (Synchronous,block) |
Immediate |
Scheduling work immediately in the current process, synchronizing (Synchronous,block) |
Newthread |
Dispatching work in a new thread (Asynchronous,no-block) |
Taskpool |
Dispatching work in the Task Factory (Asynchronous,no-block) |
ThreadPool |
Scheduling work in a thread pool (asynchronous,no-block) |
Sample code Rxconcurrencysample Download
Resources:
The reactive Extensions (Rx) ...
Reactive Extensions (RX) Introduction
. NET parallel Programming-reactive Extensions (Rx) concurrency analysis