DEVHOL202 – Curing the asynchronous blues 
with the Reactive Extensions for .NET 
Introduction 
This Hands-on-Lab (HOL) familiarizes the reader with the Reactive Extensions for .NET (Rx). By exploring the framework 
through a series of incremental samples, the reader gets a feel for Rx͛s compositional power used to write asynchronous 
applications, based on the concept of observable collections. 
Prerequisites 
We assume the following intellectual and material prerequisites in order to complete this lab successfully: 
 Active knowledge of .NET and the C# programming language. 
 Feeling for the concept of asynchronous programming and related complexities. 
 Visual Studio 2010 and .NET 4 (prior versions can be used but the lab is built for VS2010) installation. 
 Installation of Rx for .NET 4 from MSDN DevLabs at http://msdn.microsoft.com/en-us/devlabs
What is Rx? 
Rx can be summarized in the following sentence which can also be read on the DevLabs homepage: 
Rx is a library for composing asynchronous and event-based programs using observable collections. 
Three core properties are reflected in here, all of which will be addressed throughout this lab: 
 Asynchronous and event-based – As reflected in the title, the bread and butter of Rx͛s mission statement is to 
simplify those programming models. Everyone knows what stuck user interfaces look like, both on the Windows 
platform and on the web. And with the cloud around the corner, asynchrony becomes quintessential. Low-level 
technologies like .NET events, the asynchronous pattern, tasks, AJAX, etc. are often too hard. 
 Composition – Combining asynchronous computations today is way too hard. It involves a lot of plumbing code 
that has little to nothing to do with the problem being solved. In particular, the data flow of the operations 
involved in the problem is not clear at all, and code gets spread out throughout event handlers, asynchronous 
callback procedures, and whatnot. 
 Observable collections – By looking at asynchronous computations as data sources, we can leverage the active 
knowledge of LINQ͛s programming model. That͛s right: your mouse is a database of mouse moves and clicks. In 
the world of Rx, such asynchronous data sources are composed using various combinators in the LINQ sense, 
allowing things like filters, projections, joins, time-based operations, etc. 
Lab flow 
In this lab, we͛ll explore Rx in a gradual manner. First, we͛ll have a look at the core interfaces of Rx which ship in .NET 4͛s 
Base Class Library. Once we understand those interfaces (and their relationship with IEnumerable<T>), we͛ll move on to 
show how the Rx libraries allow for creating simple observable sequences using factory methods. This allows for some 
basic experimentation. As we proceed, we͛ll introduce how to bridge with existing asynchronous event sources such as 
.NET events and the asynchronous pattern. Showing more query operators as we move along, we͛ll end up at a point 
where we start to compose multiple asynchronous sources, unleashing the true power of Rx. 
Pdf to tiff quality - Convert PDF to tiff images in C#.net, ASP.NET MVC, Ajax, WinForms, WPF
Online C# Tutorial for How to Convert PDF File to Tiff Image File
pdf to tiff open source c#; convert pdf to grayscale tiff
Pdf to tiff quality - VB.NET PDF Convert to Tiff SDK: Convert PDF to tiff images in vb.net, ASP.NET MVC, Ajax, WinForms, WPF
Free VB.NET Guide to Render and Convert PDF Document to TIFF
pdf to tiff online converter; pdf to tiff converter online
Exercise 1 – Getting started with Rx interfaces and assemblies 
Objective:  Acquiring basic knowledge of the IObservable<T> and IObserver<T> interfaces that ship in the .NET 4 BCL and 
the role of the Rx DevLabs release System.Reactive and System.CoreEx assemblies. 
1. Open Visual Studio 2010 and go to File, New, Project… to create a new onsole Application project in #. Make 
sure the .NET Framework 4 target is set in the dropdown box at the top of the dialog. 
2. In the Program.Main method in the Program.cs source file, explore the System namespace by typing the 
following fragment of code: 
System.IObs
This shows the two core interfaces around which Rx is built. Starting from .NET 4, those interfaces are built in to 
the Base Class Library͛s mscorlib.dll assembly. 
Note:  On other platforms supported by Rx (including .NET 3.5 SP1 and Silverlight), a separate assembly called 
System.Observable.dll has to be included in the project in order to get access to those two interfaces. This 
assembly gets installed in the same location as the other assemblies we͛ll talk about further on in this first 
exercise. 
C# PDF File Compress Library: Compress reduce PDF size in C#.net
easily and quickly complete a high-quality PDF document compression compressing & decompression method, TIFF files compression C#.NET PDF Document Optimization.
convert pdf to tiff multiple pages; reader convert pdf to tiff
Online Convert PDF file to Tiff. Best free online PDF Tif
Using this .NET PDF to TIFF conversion control, C# developers can render and convert PDF document to TIFF image file with no loss in original file quality.
pdf to tiff converter for; pdf to tiff converter
3. To start our exploration of those interfaces, we should have a look at them. Use the Object Browser (available 
through the View menu) or use both interfaces in a piece of code and use Go to Definition from the context 
menu (or press F12). We͛ll follow the latter route here as it allows to indicate the role of both interfaces in an 
informal manner using variable names: 
IObservable<int> source; 
IObserver<int> handler; 
The interfaces should look as shown below: 
public interface IObservable<out T> 
IDisposable Subscribe(IObserver<T> observer); 
public interface IObserver<in T> 
void OnCompleted(); 
void OnError(Exception error); 
void OnNext(T value); 
} 
Both interfaces serve a complementary role. The IObservable<T> interface acts as a data source that can be 
observed, meaning it can send data to everyone who͛s interested to hear about it. Those interested parties are 
represented by the IObserver<T> interface. 
In order to receive notifications from an observable collection, one uses the Subscribe method to hand it an 
IObserver<T> object. In return for this observer, the Subscribe method returns an IDisposable object that acts as 
a handle for the subscription. Calling Dispose on this object will detach the observer from the source such that 
notifications are no longer delivered. Similarities with the += and -= operators used for .NET events are not 
accidental, but the Subscribe method provides more flexibility. In particular, an unsubscribe action can result in 
quite some bookkeeping, all of which is handled by the Rx framework. 
Observers support three notifications, reflected by the interface͛s methods. OnNext can be called zero or more 
times, when the observable data source has data available. For example, an observable data source used for 
mouse move events could send out a Point object every time the mouse has moved. The other two methods are 
used to signal successful or exceptional termination. 
Background:  Those two interfaces are the dual to IEnumerable<T> and IEnumerator<T>. While this deep duality 
may sound frightening, it͛s a source of much beauty. First of all, the property of duality between those interfaces 
can be explained in two simple English words: push versus pull. Where an observable data source pushes data at 
its observers, enumerable data sources are being pulled by an enumerator to receive data (typically using the 
foreach language construct). As a result of this duality, all of the LINQ operators that apply in one world have a 
corresponding use in the other world. We͛ll see this illustrated in later exercises. 
4. Even though we͛ve shown those interfaces, we͛ll resist the temptation to implement them. Instead, the next 
exercise will explain how to create observable sequences using functionality in the Rx library. To recap the 
usage, we͛ll start by writing a bit of non-functional code (indeed, this won͛t work just yet): 
IDisposable subscription = source.Subscribe(handler); 
Console.WriteLine("Press ENTER to unsubscribe..."); 
Console.ReadLine(); 
subscription.Dispose(); 
VB.NET Image: Robust OCR Recognition SDK for VB.NET, .NET Image
Once images and documents are loaded in VB.NET project, input quality will be enhanced with Images exported can be Png, Jpeg, Tiff, image-only PDF or Bmp.
pdf to tiff open source; convert multipage pdf to multipage tiff
C# PDF Convert to Jpeg SDK: Convert PDF to JPEG images in C#.net
library component toolkit, C# developers can easily and quickly convert a large-size multi-page PDF document to a group of high-quality separate JPEG image
pdf to tiff conversion online; pdf to tiff converter without watermark
5. While the above shows a typical use pattern of observable sequences, you may have noticed there͛s little one 
can do with an IObservable<T> object, other than subscribing to it: 
6. In order to make observable sequences more useful, the Rx library provides a whole bunch of operators to apply 
operations to observable sequences and to compose them. So, while the .NET 4 BCL ships bare bones interfaces, 
Rx provides rich functionality for them. In order to leverage those, go to the Solution Explorer, right click on the 
project͛s node, choose Add Reference…, and go to the .NET tab. In there, you should find System.Reactive as 
well as System.CoreEx: 
Add both of those to your project. In this lab, we won͛t cover the System.Interactive assembly which contains 
extensions for LINQ to Objects (leveraging the property of duality we mentioned briefly earlier). 
Note:  Your actual version number for the Rx assembly may vary from those shown in the screenshot above. As 
long as you got a later version than the one shown, you should be fine to go. 
Tips:  If you can͛t find the assemblies shown in the screenshot above, first wait a couple of seconds since the 
new Visual Studio 2010 dialog has been made asynchronous with regards to reference folder scanning. Also 
notice this doesn͛t retain an alphabetical ordering, so you may have to trigger a sort on the first column. If the 
assemblies still don͛t show up, check Rx is installed by checking ͞Add or remove programs͟ in the ontrol Panel. 
VB.NET PDF Convert to Jpeg SDK: Convert PDF to JPEG images in vb.
VB.NET Excel, VB.NET PowerPoint, VB.NET Tiff, VB.NET Able to Convert PDF to JPEG file in .NET WinForms Export high quality jpeg file from PDF in .NET framework.
how to change pdf to tiff; convert pdf to tiff using c#
VB.NET PDF File Compress Library: Compress reduce PDF size in vb.
3.pdf"; String outputFilePath = Program.RootPath + "\\" 3_optimized.pdf"; 'create optimizing Compression = PDFCompression.DCTDecode 'set quality level, only
converting pdf to tiff file; convert pdf to tiff format
7. You may wonder why we need two assemblies. The System.Reactive assembly is what contains the operators for 
observable sequences, implemented as extension methods as we shall see in just a moment. Since many of 
those operators need to introduce concurrency (a necessary evil in the face of asynchronous programming), the 
notion of a scheduler was introduced. This functionality lives in System.CoreEx to achieve a decent architectural 
layering whereby both System.Reactive and System.Interactive never deal with concurrency directly but defer to 
particular scheduler implementations. Later on, we͛ll see operators like ObserveOn that use schedulers. 
8. With those assemblies added, we should now see more methods on IObservable<T> objects. Since those are 
extension methods, a little experiment will reveal two buckets of additional methods. Eliminate all of the 
namespace imports other than System and observe the IntelliSense auto-completion list on IObservable<T>: 
Notice the Subscribe extension methods being added through the System namespace. Those overloads allow 
one to avoid implementing the IObserver<T> interface at all, since one can specify any of the three handler 
methods (OnNext, OnError, OnCompleted) using delegates. For example: 
IDisposable subscription = source.Subscribe( 
(int x) => { 
Console.WriteLine("Received {0} from source.", x); 
}, 
(Exception ex) => { 
Console.WriteLine("Source signaled an error: {0}.", ex.Message); 
}, 
() => { 
Console.WriteLine("Source said there are no messages to follow anymore."); 
); 
Exercise:  It͛s left as an exercise for the reader to eliminate any excessive syntax in the sample above, such as 
types than can be inferred, redundant curly braces, etc. 
VB.NET Image: RasterEdge JBIG2 Codec Image Control for VB.NET
control in VB.NET is capable of embedding compressed bitonal images into PDF files and decompress images from PDF files quickly with the smallest quality loss.
how to convert pdf into tiff; batch convert pdf to tiff
C# Create PDF from Tiff Library to convert tif images to PDF in C#
PDF files are created from tiff with high quality using .NET PDF SDK for C#.NET. Support to combine multiple page tiffs into one PDF file.
how to convert pdf file to tiff for; bulk pdf to tiff converter
9. To see operators that can be applied to IObservable<T> objects, add a using directive to import the System.Linq 
namespace. ͞Dot into͟ our source object again, this time revealing a whole bunch of operators. For those 
familiar with LINQ, try finding some of your favorite operators such as Where, Select, etc. 
Conclusion:  The IObservable<T> and IObserver<T> interfaces represent a data source and a listener, respectively. In 
order to observe an observable sequence͛s notifications, one gives it an observer object using the Subscribe method, 
receiving an IDisposable object that be used to unsubscribe. While those interfaces are in the .NET 4 L, they͛re only 
available through a System.Observable assembly on other platforms. To enable rich functionality over observable 
sequences (as we͛ll discuss thoroughly in what follows), System.Reactive provides a series of extension methods that can 
be imported through the System and System.Linq namespaces. 
Exercise 2 – Creating observable sequences 
Objective:  Observable sequences are rarely provided by implementing the IObservable<T> interface directly. Instead a 
whole set of factory methods exist that create primitive observable sequences. Those factory methods provide a good 
means for initial exploration of the core notions of observable sources and observers. 
1. Ensure the project setup of Exercise 1 is still intact, i.e. references to System.CoreEx and System.Reactive are in 
place and both the System and System.Linq namespaces are imported in your Program.cs file. Also ensure the 
following skeleton code is still present: 
IObservable<int> source = /* We’ll explore a set of factory methods here */
IDisposable subscription = source.Subscribe( 
 => Console.WriteLine("OnNext:  {0}", x), 
ex => Console.WriteLine("OnError: {0}", ex.Message), 
() => Console.WriteLine("OnCompleted") 
); 
2. In the above, we͛ll substitute the comment for various primitive sources and observe their behavior. We͛ll also 
contrast those with enumerable sequences. Since observable sequences sometimes introduce concurrency to 
pump out their notifications (required for asynchrony), we should prevent the program from quitting while the 
subscription is active. We͛ll hold the main thread by using onsole.ReadLine to do so prior to calling Dispose on 
the subscription: 
Console.WriteLine("Press ENTER to unsubscribe..."); 
Console.ReadLine(); 
subscription.Dispose();
3. We͛ll start by looking at the Empty factory method: 
IObservable<int> source = Observable.Empty<int>(); 
Running this code produces the following output: 
OnCompleted
In order words, the empty sequence simply signals completion to its observers by calling OnCompleted. This is 
very similar to LINQ to Object͛s Enumerable.Empty or an empty array (e.g. new int[0]). For those enumerable 
sequences, the first call to the enumerator͛s MoveNext method will return false, signaling completion. 
Background:  One may wonder when observable sequences start running. In particular, what͛s triggering the 
empty sequence to fire out the OnCompleted message to its observers? The answer differs from sequence to 
sequence. Most of the sequences we͛re looking at in this exercise are so-called cold observables which means 
they start running upon subscription. This is different from hot observables such as mouse move events which 
are flowing even before a subscription is active (there͛s no way to keep the mouse from moving after all…). 
4. Besides the OnCompleted message, OnError is also a terminating notification, in a sense no messages can follow 
it. Where Empty is the factory method creating an observable sequence that immediately triggers completion, 
the Throw method creates an observable sequence that immediately triggers an OnError message to observers: 
IObservable<int> source = Observable.Throw<int>(new Exception("Oops"));
Running this code produces the following output: 
OnError: Oops
Background:  The OnError message is typically used by an observable sequence (not as trivial as the one simply 
returned by a call to Throw) to signal an error state which could either originate from a failed computation or 
the delivery thereof. Following the semantic model of the LR͛s exception mechanism, errors in Rx are always 
terminating and exhibit a fail-fast characteristic, surfacing errors through observer handlers. More advanced 
mechanisms to deal with errors exist in the form of handlers called Catch, OnErrorResumeNext and Finally. We 
won͛t discuss those during this HOL, but their role should be self-explanatory based on corresponding language 
constructs in various managed languages. 
5. One final essential factory method or primitive constructor is called Return. Its role is to represent a single-
element sequence, just like a single-cell array would be in the world of IEnumerable sequences. The behavior 
observed by subscribed observers is two messages: OnNext with the value and OnCompleted signaling the end 
of the sequence has been received: 
IObservable<int> source = Observable.Return(42);
Running this code produces the following output: 
OnNext: 42 
OnCompleted
Background:  Return plays an essential role in the theory behind LINQ, known as monads. Together with an 
operator called SelectMany (which we͛ll learn about more later on), they form the primitive functions needed to 
leverage the power of monadic computation. More information can be found by searching the web using monad 
and functional as the keywords. 
6. At this point, we͛ve seen the most trivial observable sequence constructors that are intimately related to an 
observer͛s triplet of methods. While those are of interest in certain cases, more meaty sequences are worth to 
explore as well. The Range operator is just one operator that generates such a sequence. Symmetric to the same 
operator on Enumerable, Range does return a sequence with 32-bit integer values given a starting value and a 
length: 
IObservable<int> source = Observable.Range(5, 3);
Running this code produces the following output: 
OnNext: 5 
OnNext: 6 
OnNext: 7 
OnCompleted
Note:  As with all the sequences mentioned in this exercise, Range is a cold observable. To recap, this simply 
means that it starts producing its results to an observer upon subscription. Another property of cold observable 
sequence is that every subscription will cause such reevaluation. Thus, if two calls to Subscribe are made, both 
of the observers passed to those calls will receive the messages from the observable. It͛s not because the data 
observation has run to completion for one observer that other observers won͛t run anymore. Whether or not 
the produced data is the same for every observer depends on the characteristics of the sequence that͛s being 
generated. For deterministic and ͞purist functional͟ operators like Return and Range, the messages delivered to 
every observer will be the same. However, one could imagine other kinds of observable sequences that depend 
on side-effects and thus deliver different results for every observer that subscribes to them. 
7. To generalize the notion of sequence creation in terms of a generator function, the Generate constructor 
function was added to Rx. It closely resembles the structure of a for-loop as one would use to generate an 
enumerable sequence using # iterators (cf. the ͞yield return͟ and ͞yield break͟ statements). To do so, it takes a 
number of delegate-typed parameters that expect function to check for termination, to iterate one step and to 
emit a result that becomes part of the sequence and is sent to the observer: 
IObservable<int> source = Observable.Generate(0, i => i < 5, i => i + 1, i => i * i);
Running this code produces the following output: 
OnNext: 0 
OnNext: 1 
OnNext: 4 
OnNext: 9 
OnNext: 16 
OnCompleted
Note:  A sister function called GenerateWithTime exists that waits a computed amount of time before moving 
on to the next iteration. We͛ll look at this one in just a moment. 
8. One operator that may seem interesting from a curiosity point of view only is called Never. It creates an 
observable sequence that will never signal any notification to a subscribed observer: 
IObservable<int> source = Observable.Never<int>();
Running this code shouldn͛t produce any output till the end of mankind.  
Background:  One reason this operator has a role is to reason about composition with other sequences, e.g. 
what would it mean to concatenate a finite and an infinite sequence? Should the result also exhibit an infinite 
characteristic? Those answers are essential to ensuring all of the Rx semantics make sense and are consistent 
throughout various operators. esides the operator͛s theoretical use, there are real use cases for it as well. For 
example, you may use it to ensure a sequence never terminates by avoiding an OnCompleted handler getting 
triggered. Another use is to test whether an application does not hang in the presence of non-termination. 
9. Where the Subscribe method has an asynchronous characteristic, other blocking operators exist to observe a 
sequence in a synchronous manner. One such operator is called Run
First of all, let͛s formalize ͞asynchronous͟. It͛s near to impossible to say something is asynchronous in itself 
without mentioning two parties. In particular, the thread calling the Subscribe method on an observable 
sequence is not blocked till the sequence runs to completion, which may happen on another thread. That is, 
Subscribe is asynchronous in that the caller is not blocked till the observation of the sequence completes. 
For demos and testing it͛s often useful to perform a ͞blocking subscribe͟ such that the caller is blocked till the 
observable sequence triggers OnError or On n ompleted to the observer. That͛s what Run is all about: 
IObservable<int> source = Observable.Range(0, 10); 
source.Run( 
 => Console.WriteLine("OnNext:  {0}", x), 
ex => Console.WriteLine("OnError: {0}", ex.Message), 
() => Console.WriteLine("OnCompleted") 
); 
In here, we won͛t get to the next statement till the sequence completes gracefully or exceptionally. 
10. Finally, let͛s inspect the behavior of an observable sequence by looking at it through the lenses of the debugger 
in Visual Studio. We͛ll use the following fragment to do so: 
IObservable<int> source = Observable.GenerateWithTime( 
0, i => i < 5, 
i => i + 1, 
i => i * i, i => TimeSpan.FromSeconds(i)); 
using (source.Subscribe( 
x  => Console.WriteLine("OnNext:  {0}", x), 
ex => Console.WriteLine("OnError: {0}", ex.Message), 
() => Console.WriteLine("OnCompleted"
)) 
Console.WriteLine("Press ENTER to unsubscribe..."); 
Console.ReadLine(); 
This sample uses a slightly different operator called GenerateWithTime that allows specifying iteration time 
between producing results, dependent on the loop variable. In this case, 0 will be produced upon subscription, 
followed by 1 a second later, then 4 two seconds later, 9 three seconds later and 16 four seconds later. Notice 
how the notion of time – all important in an asynchronous world – is entering the picture here.
Note:  Typically you won͛t immediately dispose a subscription by means of a using block. In this sample case it 
works fine since the code block blocks for user input. In most cases you͛ll store the IDisposable object in order to 
dispose it at a later time, or even don͛t bother to dispose it (e.g. for infinite sequences like timers). 
a. Set a breakpoint on the highlighted lambda expression body using F9. Notice you need to be inside the 
lambda body with the cursor in the editor in order for the breakpoint to be set on the body and not the 
outer method call to Subscribe.  
b. Start running the program by pressing F10 and step down in the code using F10. You͛ll not see the 
breakpoint being hit just yet and will effectively reach the Console.ReadLine call: 
c. What͛s happening here is that the call to Subscribe started a background thread to pump out the 
observable sequence͛s values based on a timer. We͛ll learn more about the concurrency aspects of Rx 
later on, but for now let͛s verify this hypothesis by looking at the Threads window in the debugger 
(Debug, Windows, Threads or CTRL+D,T): 
Documents you may be interested
Documents you may be interested