Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Reactive Programming for .NET Developers
Reactive Programming for .NET Developers

Reactive Programming for .NET Developers: Get up and running with reactive programming paradigms to build fast, concurrent, and powerful applications

eBook
€8.99 €29.99
Paperback
€36.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Reactive Programming for .NET Developers

Chapter 1. First Steps Toward Reactive Programming

Thanks for buying this guide to Reactive Programming and Reactive Extensions for .NET.

This book will give you an expert overview about the magical world of programming, also known as programming live data or real-time data, instead of programming static data as happens with any other usual programming paradigm.

Do you know Microsoft Excel?

Excel is a software that lets you write raw numbers and functions in a proprietary mathematical form or through a simple scripting programming language (VBA).

The magic happens when you write an Excel function, such as =A1+A2, which means that the current cell value will be the sum of the values contained in the A1 and A2 cells.

This simple function creates a subscription to the events of cells A1 and A2. This means that any time you update the value of any of these two cells, the function will return a new value. This is the simplest example of functional and reactive programming available.

Now that we have an idea of what reactive is, it is easy to explain that this book will guide developers with any background knowledge about reactive programming toward the understanding of the reactive programming paradigm with a lot of examples of using Reactive Extensions (Rx) for .NET.

This chapter will give an overview of what Reactive Programming (RP) is and how it works, starting with programming paradigms and later diving into the RP structure following the schema:

  • Programming paradigms
  • Dataflow programming
  • Functional programming
  • Reactive programming

Programming paradigms

Once upon a time, programming languages where extremely different from the ones we have today.

The first-generation programming language was the machine-code one. It was made against the hardware itself, and for most, programming in such way meant creating hardware solutions like moving jumpers or switches or adding/removing cables.

The second generation of programming languages was the assembly language (such as Assembler). The name was related to the assembling stage of these languages into a machine level one that is able to run in the CPU execution pipelines. This language generation was the first made with text, although it was tightly coupled with hardware architectures.

The third generation of programming languages started the age of English-like languages that were able to run on top of hardware specifications with their own instruction set, no longer coupled with the lower hardware level. It started the reusability era.

These languages were not made in real CPU executable code. Programmers did their job in a high-level programming language that, after the compilation stage, translated into a lower-level one that was able to run into the CPU execution pipeline. At the beginning of the high-level programming era, the most diffused languages where IBM ® Fortran and COBOL.

Modern languages, such as .NET, Java, and C/C++, are all of the same generation as their grandparents of the 1950s. Obviously, the current languages have improved features and abilities, because of the long evolution time.

The main differentiation between the previous programming languages and the current ones is the programming paradigm—something like a programming approach of structured methodology that changes the way a programmer creates software.

The oldest one is the imperative  programming paradigm. It is made of a direct sequence of steps, usually numbered from 1 to N, that simply executes in a forward-only fashion. In these stages, the ability to jump forward or backward with commands, such as GoTo, was definitely a killing feature, while now, with modern programming paradigms, it is absolutely avoided. By programming with such an approach, a simple application made to sum two values was a simple sequence of steps, or instructions, that altogether achieved the desired goal. Here is an example in C#:

Console.WriteLine("Step counter: RUNNING"); 
 
Console.WriteLine("Write the starting value"); 
var startingValue = int.Parse(Console.ReadLine()); 
 
//value entering starting point 
REPEAT: 
Console.WriteLine("Write the ending value"); 
var endingValue = int.Parse(Console.ReadLine()); 
 
if (endingValue <= startingValue) 
{ 
    Console.WriteLine("ending value must be greater than starting value"); 
    goto REPEAT; 
} 
 
//this counter represents the distance between startingValue and endingValue 
var counter = 0; 
 
//increments the counter until needed to reach the endingValue 
COUNT: 
if (endingValue > ++counter + startingValue) 
    goto COUNT; 
 
Console.WriteLine("You need {0} steps to reach {1} from {2}", counter, endingValue, startingValue); 
Console.WriteLine("END"); 

As you can see in the preceding example, the whole program is only a list of steps where the current actor is at once the computer asking for something on the console and the user writing some response on the console. The program is unable to do multiple things together. Either the computer places a question to the user, or the user enters a digit or something on the keyboard to give the computer a command or some data.

Note

C# is a general purpose programming language supporting imperative, procedural, declarative, object-oriented, component-oriented, service-oriented, and functional programming paradigms all together.

There are no interaction constructs (for, for...each) available in imperative programming, and there is no code factorization into subroutines able to abstract and make reusable single portions of code.

The check logic against the user value is available through a simple GoTo statement that is able to move the control's flow pointer (the actual execution row) to a newly desired position. Regarding this check logic, the execution flow simply goes back to some previous line executing and entering a destination value.

Similarly, when it is time to count the distance between the two given values, the logic again uses the GoTo statement, changing the current state of the counter variable to the updated value. It is the last time the variable will contain the required result.

Note

It is interesting that throughout the imperative programming paradigm, C# is even faster than when programming in an object-oriented one, because of the higher usage of the stack memory, instead of the heap memory that is slower.

If you are interested in code optimization and high performance programming, you may find it interesting to read my other book Learning .NET High Performance Programming.

In imperative programming languages, such as Fortran, Pascal, or COBOL, there was a number for each row to give developers the ability to create interactive constructs, such as recurring jobs or any other interaction logic, by jumping between rows.

Obviously, this choice is not available in modern general-purpose languages, such as C#, which give the same feature with the use of a label (in the preceding example, we used Repeat and Count) instead of the row number. The result is the same.

To understand imperative programming, we must understand the meaning of the state. An application's state is the sum of all the data usually available within the code through fields, properties, and variables. When we started the preceding code, the application state was empty (we will ignore the Common Language Runtime (CLR) stuff that is in the memory together with our data). During the execution, some variables (startingValue and endingValue) became available by asking data from the user.

Later, a counter variable will make the most of the work to find the distance between the two numbers. What is the heart of the imperative programming paradigm is the status change that the code makes against available variables. As visible, the counter variable becomes incremented until the wanted value is found.

This status change still happens in other paradigms such as procedural-programming or object-oriented programming, although these paradigms bring to a higher level abstraction of data structures or a better code reusability.

Dataflow programming

Changing the application state is not something wrong by itself, but there are different programming approaches that may produce better results and together give the developer a more pleasant working experience. A typical use case happens when we deal with in-move data (or living data or data stream), where we may find that using interaction logic constructs that change state, such as if, for, and so on, is a poor performing choice together with a poor design. In-move data is any kind of data stream, such as a video stream, an application insights stream, and so on. Because of its statelessness, it is obvious that a stateless programming approach offers better results than a state-driven one.

We are used to dealing with static data, such as a variable, a database, or anything else such as some binary- or string-based data. All such data is data-at-rest, static data, or simply data.

As an example if we execute a select statement against a relational database, we will always have a result set containing the exact value contained in the database table at the specific time we executed the query. A second later, the table could experience an update statement that could change any row's data without the first client (the one executing the select statement) receiving an update on such data changes. To address these kinds of data changes without having to face issues between different relational database clients, there are optimistic and pessimistic concurrency checks (a bit outside the scope of this book). Obviously, the less we need to synchronize code to access a concurrent resource, the better our code will perform.

In imperative programming, control-flow is responsible for the good execution of the application. Such flow is usually made of multiple code rows that do something on input/output ports and somehow alter the application's state until the desired result is achieved, whereas in dataflow programming, data flows in and out of the different stages of a flowchart, as it behaves in a workflow.

Obviously, the different types of programming will greatly change the developers' experience and programming capability of the language. It is very difficult (and conceptually a bit wrong) to compute something by executing some interaction logic in data flow programming, because this kind of programming is simply outside the core design of the programming paradigm.

A practical example can be seen in data integrational , Extract, Transform, and Load (ETL) workflows, such as those available in SQL Server Integration Services (SSIS), as shown in the following screenshot. An ETL workflow has the task of reading (extracting) data from a data source (relational or not) and mapping (transforming) such data by grouping or aggregating it with other data sources or by executing transforming functions. Then, data flows (loads) into a target data store (relational or not) for future simplified access. SSIS is the tool for designing these kinds of workflows within the SQL Server Business Intelligence suite.

Dataflow programming

A SSIS dataflow task doing some transformations on data from a relational database

Generally speaking, outside the SQL server-oriented implementation of SSIS, within data flow programming, instead of having a huge code base in a high-level code, we have something like a data workflow. A digraph (directed graph)—an ordered version of a usual flowchart. Here is an example:

Dataflow programming

A simple representation of a dataflow digraph made of three recurring stages

Within the Microsoft universe, the only data flow programming compliant language is the Microsoft Visual Programming Language available for the Microsoft Robotics Developer Studio environment for robotics programming. Instead, SSIS simply uses data flows to handle data integrations between databases.

Statelessness

The unavailability of the state, a key concept of data flow programming, is the opposite of what happens in all imperative or object-oriented programming-based applications. This behavior drastically changes the programming experience.

A stateless design never stores (temporary or persisted) application or user data with the need of changing it in time for computational needs.

We cannot use temporary variables to store changeable values, such as the total of an invoice. We cannot use an index to jump around a collection or an array, and we cannot iterate it. Obviously, if we need to write a function that needs a variable, we cannot use a variable anymore; in other words, we can't use variables that act as a business logic state persistence.

When we write a function, the data will simply have an origin, a target, and one or multiple transformations in multiple stages.

Thanks to this stateless design of the whole application, it is easy to see that each stage can run on a different thread together and each input or output endpoint can run on another thread and so on. The stateless design is the key that makes the design able to scale out quite perfectly according to Amdahl's Law.

As well as performance results, a stateless design brings higher testability rates of the whole application (bear in mind ASP.NET WebForms versus ASP.NET MVC) together with a more modern approach in programming style that avoids the use of interactive loops such as for, for...each, and relatives.

The data-driven approach

The last evolution of the imperative programming paradigm is object-oriented programming. Such paradigms request we model our business world into a high-level domain model. This means that, in our code, we will find an object representing any living entity of our business model; a invoice or a customer are examples of such objects. Such models drive business logic. They do not need to be persisted in a one-to-one representation from the model to the persistence store (usually, a relational database). This approach is called domain-driven design. The opposite of such an approach is the data-driven design that makes direct actions against data without a real discrimination between data and business.

Because of the intrinsic behavior of dataflow programming, a data-driven design is the natural choice when designing a solution based on such programing paradigms.

But in the modern .NET-based programming style, the use of business-related entities in the various stages of the dataflow execution is available and suggested too.

Data streams

A data stream is the flow of some data in time, usually of a unique format, that is available to one or multiple readers.

Examples are television video streams, YouTube video streams, Twitter or RSS feeds, Azure EventHub, and so on. Those who are used to C# programming will remember the namespace System.IO that contains different classes made for stream programming, such as BinaryReader/BinaryWriter that makes available streaming any CLR low-level type or StreamReader/StreamWriter that makes available streaming any text supporting various encodings from ASCII to UTF32.

In other words, a data stream is some data in a specific time instance. Time is the key concept for understanding a data stream. It is all about running data or in-move data. Without the time component, data can never flow in a stream.

Depending on the stream, it may support seeking operations, such as the ability to go forward and backward along the stream to start flowing data exactly at the desired time. Television video streams do not support such a feature. Microsoft Azure EventHub (a data stream) instead supports the feature in a configured time window of usually some hours.

The Azure EventHub is a paralleled stream service for streaming any data, usually used for Internet of Things (IoT) devices, telemetry values, or diagnostic purposes as an application insights collection. A similar choice within the Azure offering is the IoT Hub, another streamed service totally oriented to IoT devices that support more specific protocols.

Observer pattern

The Observer pattern, is a published subscribe style pattern; it defines the ability to register for data change or event signaling. Although written words may be something new to read about, the observer pattern is something absolutely overused in the event-driven programming paradigm of the Microsoft oriented languages in the last 20 years.

When we handle the Button click event, either in Visual Basic (from version 1 to 6) or in modern .NET Windows Forms, WPF applications, or even ASP.NET applications, we are simply using an implementation of the observer pattern.

The pattern defines an event generator, also known as subject, that fires the event and one or multiple event listeners or observers (in .NET, also known as event handlers) that will do something in reaction to the data state change or event signaling.

When dealing with data flow programming, the observer pattern is the one responsible for the acknowledgment between stages of the new data available. Each stage informs the following stages of new data available with a signal. Stages do not know about the overall design of the digraph. They simple signal the new data availability event; all subsequent stages that are observing the previous one for new data will be then acknowledged. This design makes useless the need of an overall data state, thus the design is stateless. Each stage observes or is being observed. That is all. Such data flowing between stages are data streams.

Functional programming

Functional programming is a programming paradigm that relies on the functional transformation of data between stages, not so different from the dataflow programming we just saw. The main addendum to the data flow paradigm is that, within the functional one, there is a specific functional transformation, while in the data flow paradigm such transformations occur in a specific idiom-based way that can be functional-based, script-based (imperative paradigm), component-based, or anything else.

In functional programming, data is always immutable and functions are responsible for data transformation. Anything in functional style is a data transformation. Although a decisional statement (if) cannot exist, a functional transformation from data containing predicate to data containing the Boolean result may occur:

//procedural style 
var sourceData = new { TotalAmount = 12345.67, PaidAmount = 12345.67 }; 
if (sourceData.PaidAmount == sourceData.TotalAmount) 
{ 
    //do something 
} 
 
//functional style 
//a simple enumerable 
new[] { new { TotalAmount = 12345.67, PaidAmount = 12345.67 } } 
//transformation block 
.Select(x => new 
{ 
    x.TotalAmount, 
    x.PaidAmount, 
    CanContinue = x.TotalAmount == x.PaidAmount, 
}) 
//if 
.Where(x => x.CanContinue) 
//do something 
.ToArray(); 

A widely known design pattern is the data mapper one. This design tries to decouple and translate objects of a layer (for historic purposes, the domain layer) into another one (for historic purposes, the data model one).

Here is a simple procedural (imperative with subroutines) programming style example in C#:

class Program 
{ 
    static void Main(string[] args) 
    { 
        //retrieve invoices from DB 
        var invoicesFromDB = GetInvoicesFromDB(); 
 
        //map those invoices to business model objects 
        var invoicesForBusiness = ConvertInvoicesForBusiness(invoicesFromDB); 
    } 
 
    /// <summary> 
    /// Reads invoices from a (fake) database 
    /// </summary> 
    /// <returns></returns> 
    static InvoiceFromDB[] GetInvoicesFromDB() 
    { 
        var result = new InvoiceFromDB[3]; 
 
        result[0] = new InvoiceFromDB 
            { 
                CustomerName = "Mr. Black", 
                Number = "100/2015/BBC", 
                BaseAmount = 24560, 
                VATMultiplier = 1.22, 
            }; 
 
        result[1] = new InvoiceFromDB 
            { 
                CustomerName = "White Co Ltd", 
                Number = "240/2015/BBC", 
                BaseAmount = 422480, 
                VATMultiplier = 1.22, 
            }; 
 
        result[2] = new InvoiceFromDB 
            { 
                CustomerName = "Green Woods inc.", 
                Number = "22/2015/BBC", 
                BaseAmount = 8500, 
                VATMultiplier = 1.22, 
            }; 
 
        return result; 
    } 
 
    /// <summary> 
    /// Converts invoices from database to invoices for business needs 
    /// </summary> 
    static InvoiceBusiness[] ConvertInvoicesForBusiness(InvoiceFromDB[] source) 
    { 
        var result = new InvoiceBusiness[source.Length]; 
 
        for (int i = 0; i < source.Length; i++) 
            result[i] = new InvoiceBusiness 
            { 
                Number = source[i].Number, 
                CustomerName = source[i].CustomerName, 
                BaseAmount = source[i].BaseAmount, 
                VATMultiplier = source[i].VATMultiplier, 
            }; 
 
        return result; 
    } 
} 
 
public class InvoiceFromDB 
{ 
    public string CustomerName { get; set; } 
    public string Number { get; set; } 
    public double BaseAmount { get; set; } 
    public double VATMultiplier { get; set; } 
} 
 
public class InvoiceBusiness 
{ 
    public string CustomerName { get; set; } 
    public string Number { get; set; } 
    public double BaseAmount { get; set; } 
    public double VATMultiplier { get; set; } 
    public double Total 
    { 
        get { return BaseAmount * VATMultiplier; } 
    } 
} 

In a functional style, the same program will benefit from the use of the enumerator pattern (for static data such as this one) or triggers that will notify for observed data changes.

Later, the transformation logic will take place within a function.

Here is the same preceding example in a functional style made with LINQ querying in C#:

class Program 
{ 
    static void Main(string[] args) 
    { 
        var businessInvoices = 
            //stage 1 - read db data 
            GetInvoicesFromDB() 
            //stage 2 - make transfomation 
            .Select(dbinvoice => new InvoiceBusiness 
            { 
                Number = dbinvoice.Number, 
                BaseAmount = dbinvoice.BaseAmount, 
                CustomerName = dbinvoice.CustomerName, 
                VATMultiplier = dbinvoice.VATMultiplier, 
            }) 
            //force execution of the whole enumerator 
            .ToArray(); 
    } 
 
    static IEnumerable<InvoiceFromDB> GetInvoicesFromDB() 
    { 
        yield return new InvoiceFromDB 
        { 
            CustomerName = "Mr. Black", 
            Number = "100/2015/BBC", 
            BaseAmount = 24560, 
            VATMultiplier = 1.22, 
        }; 
 
        yield return new InvoiceFromDB 
        { 
            CustomerName = "White Co Ltd", 
            Number = "240/2015/BBC", 
            BaseAmount = 422480, 
            VATMultiplier = 1.22, 
        }; 
 
        yield return new InvoiceFromDB 
        { 
            CustomerName = "Green Woods inc.", 
            Number = "22/2015/BBC", 
            BaseAmount = 8500, 
            VATMultiplier = 1.22, 
        }; 
    } 
} 
 
public class InvoiceFromDB 
{ 
    public string CustomerName { get; set; } 
    public string Number { get; set; } 
    public double BaseAmount { get; set; } 
    public double VATMultiplier { get; set; } 
} 
 
public class InvoiceBusiness 
{ 
    public string CustomerName { get; set; } 
    public string Number { get; set; } 
    public double BaseAmount { get; set; } 
    public double VATMultiplier { get; set; } 
    public double Total 
    { 
        get { return BaseAmount * VATMultiplier; } 
    } 
} 

What makes the preceding example different from the previous one is that the GetInvoicesFromDB method returns an enumerable collection. Although an array is enumerable too, an array is a finite item collection. In the procedural example, all contained objects must already be in our memory before the method returns values creating a huge data state. Later, in the imperative example, such a state will be changed by the other method ConvertInvoicesForBusiness that is responsible for creating business objects containing business stuff (Total in the preceding example).

In the functional style example, instead of having an interactive statement that processes data in the memory, we will simply write a new function able to transform the data-oriented object into the business-oriented one. This transformation is declaratively defined with a function. The function simply states how the transformation must happen. Thus, to trigger the concrete computation and the storage (in memory) of the transformed data, we will use the .ToArray() LINQ extension method that will evaluate the functional result and store such results into a finite item collection, the array.

Note

We will delve more deeply into functional programming and functional reactive programming in Chapter 8 , F# and Functional Reactive Programming, and Chapter 9 , Advanced FRP and Best Practices, of this book.

Reactive programming

At this point, the preceding functional programming examples should convince any reader that data-driven programming of in-move data in many programming scenarios may achieve a higher performance than imperative programming could ever do.

Reactive programming is the art of programming the propagation of changes. Think of an Excel function =A1+B2. This function will always contain the sum of the two cells; it will never contain a raw (or static) value that represents the sum at a specific time. It will always contain the updated sum of the two cells' values. Anytime the related cells raise a value update event (A1 and A2), the resulting cell will update the sum and show the new value. In C#, a similar behavior is available in a computed property, where the result is available only as a computation instead of a state value:

 public double TotalAmount { get { return 10d * 10d; } } 

Obviously, reactive programming is not simply a function or computed property. Specific designs and technologies are available and needed to develop using reactive programming. Let's start understanding such a new paradigm by reading its idea and its main characteristics and the available languages and idioms.

Reactive manifesto

The reactive programming experience starts with the reactive manifesto, the idea, the vision, the goal, and the overall design that should be behind any reactive application.

The manifesto is available here: http://www.reactivemanifesto.org.

The vision is actually simple: modern application needs are incompatible with widely used (and often legacy) designs and architectures. The goals are lovely; they are as follows:

  • A message-based overall design with improved lose-coupling (between application and external modules), improved horizontal scalability, high responsiveness, and graceful failure handling.
  • A high scalability rate means the ability to scale out with a thin overhead in a sessionless design. This traduces in the ability to handle a huge amount of tasks all together by using multiple computational systems.
  • Improved responsive design because of the event-based design. The whole application will react to any request in a short time, letting the Observer module do its job without having the subject wait for completion time.
  • Improved resiliency design because of the ability to gracefully handle applications and user faults thanks to execution context isolation, software module and data replication, and other features.

From this overview of the manifesto, you learned that reactive applications are all about the asynchronous programming of data and event messages flowing between multiple computational isolated stages.

The programming experience

Reactive programming means programming reactions to asynchronously streamed events. This means programming components that receive and produce messages. In between, we can add a transformation or a filter, or components that only produce or receive messages. Sometimes, in other programming paradigms, such message routing components are called message pump.

A time-based programming is drastically different from static data programming. For example, think of an invoice. Instead of programming its data (the total, the VAT amount, and other values), we will handle how the invoice changes in time.

Let's look at the difference, as follows:

Time stages

Imperative style

Reactive style

T0

A new Invoice object is instantiated. Its total is 0.00.

A new Invoice object is instantiated.

T1

A product line is added to the invoice. The invoice's total changes to 450.00.

A new InvoiceAdditionItem object is instantiated.

T2

A product line is added to the invoice. The invoice's total changes to 1450.00.

A new InvoiceAdditionItem object is instantiated.

T3

A product line is added to the invoice. The invoice's total changes to 2450.00.

A new InvoiceAdditionItem object is instantiated.

The main difference is that, in the reactive style, we have a time-based system, that is, we know exactly what the total invoice value at T3 or T2 was, even years later.

In database programming, there is the ability to create time-based tables. In reactive programming, we do something similar, but at an improved level because in reactive programming, anything is time-based and asynchronous.

A typical explanation about persist the result or all the actors of a function is that, when we persist each message, we do something more real and more similar to how data originates. While we persist the result as a data state, we persist something easier to read later. This second choice is an easier way of programming and is often less disk consuming within a database server, although it may bring unwanted mistakes and further updates of data-state because of some events or needs.

A simple example is available in any Excel worksheet. If Excel was not reactive, at the A1 cell value update, the A2 cell formula pointing to A1 would not be updated, causing the developer to do more work later and exposing this work to a high error rate. Luckily, Excel is reactive; this means that any time we change any cell value, any formula will update its value.

This means that, in more cases, reactive programming behaves and performs better than state-driven programming, but this is not a universal solution. There are cases when state-driven programming is better than anything (typically, when dealing with other state-driven systems), and there are cases when we need to create a lightweight state to improve performances such as caching function results and so on.

When dealing with reactive programming, there are three kinds of message we can deal with. They are as follows:

  • A value message containing a new valid value
  • An error message containing an error that will flow to any message consumer
  • A completed message that signals that the flow is ending

The daily reactive programming receipt contains a lot of alterations to the flow of the subscribed streams, such as event filtering, event composition from multiple streams, event routing, event buffering (compacting multiple similar events occurring quite at the same time), event mapping (converting an event data to another one), and so on.

Change propagation and cancellation

Whenever a new message containing a value flows throughout a stream, a change propagation occurs. It is not a simple binary message containing some values; this message actually informs of a data change. As we are dealing with a value of some types and are programming a time-based system, this flowing data assumes the name data-in-motion.

Note

Data-in-motion is data in real time, such as an application insight stream. Analysis of such data happens on the same data stream, although some stages later. Data-in-motion messages may translate into other messages by morphing or mapping to other messages, but the original message can never change.

Data-in-motion starts flowing by itself in a push style. We do not need asking for a refreshed value (pull style) simply because, in a reactive application, data always flows from the subject (the data producer) to the subscribing observers, notifying always any new value with the change propagation. This means that any observer will always have the last value. Obviously, this design has a heavy constraint: we need to be always online with the data source.

However, in stateful systems, the change propagation may not occur. We simply ask for refreshed data, but in the meantime, we can work with disconnected (offline) data.

There are multiple examples of pull-based systems working with data streams. For example, any CNC system gives updates (push way) on data changes in addition to the pull-based way of reading data.

Change propagation introduces another interesting feature: the ability of specifying a timeout value by which any elaboration must occur, otherwise it is cancelled. Similar is the ability to flow a specific cancellation message to request the premature end of executing elaborations against a data changed message.

These features are now available to any stateful system thanks to Task Parallel Library (TPL) that extends the low level thread API available in the CLR with specific task-oriented features, such as the task cancellation. However, not everything may execute within a task class, while in reactive programming, we may always have the ability to cancel a value-changed message elaboration.

Linguistic characteristics

Developing applications by using the reactive programming paradigm means applying to a specified paradigm and nothing else. There is not a specific language to use to comply with reactive programming tenets. Thus, it is possible to create a reactive application by using a specific reactive-oriented language to design the overall application's design and, later, write each computational node (a computational stage on the path of the data stream) in imperative, procedural, or object-oriented programming. This is usually called an implicit reactive programming language. While languages that accept only their own constructs or components are explicit reactive programming languages.

In the Microsoft universe, an implicit reactive programming style designer is available in the BizTalk Server SDK in the map (transformational graphical-based flowchart) designer. Here, specific transformational components, called Functoids, while there is the ability to use plain .NET languages or external .NET Assemblies (libraries). Effectively, the BizTalk Server has a lot of reactive programming although different.

A reactive-based programming language may be static or dynamic, exactly as it happens for nonreactive languages. In this context, a static language is the one that statically links multiple nodes between the others. While in a dynamic reactive programming language, these links become dynamic routes that may change because of a specific logic, giving a message of the direction of a node or another with the ability to change direction per message.

A mandatory feature of any reactive programming language is the ability to manipulate different streams with features, such as the ability to merge multiple streams like a join statement makes against multiple relational tables or divide a single stream into multiple ones.

Another must-have feature is the ability to configure a Quality of service priority list of messages within the stream. This is because not all the messages have the same priority. A canonical example is about any real-time control console of hardware systems, where pressure on any key on the keyboard or any button on the board must give an immediate feedback to the user on the screen or with a light or a sound. Conversely, an informative message or notification from the system to the user does not need the same priority, because the use may simply be somewhere other than at the front of the console. This means that some millisecond of delay is valid.

Programming languages and frameworks

There are many reactive programming and compliant form programming languages available to any developer with any background.

For any Microsoft-oriented developer, the obvious choice is learning the Microsoft Reactive Extensions—a library for adding all the needed features to .NET and other languages to comply with reactive programming. This is available for .NET as Rx.NET, for JavaScript languages as RxJS, and for Visual C++ developers such as RxCpp.

For JavaScript developers, there are multiple libraries adding reactive features, such as Reactive.js, React (by Facebook), Node.js, ProAct.js, and others, available for client development in ASP.NET MVC or WebForms. Links to some of these libraries are listed here:

Reactive programming approaches

When programming using the reactive programming paradigm in implicit style, we can mix different subparadigms into the computational stages that will handle stream processing. As already mentioned, implicit reactive programming languages give the ability to design an overall (or part of) reactive application and add nonreactive programming scripts or blocks into components, controls, or modules that will execute single stream logic, such as aggregation, filtering, mapping, and so on.

In these computational blocks (that represent data flow stages), we can use functional programming, object-oriented programming, and imperative or declarative programming. For most cases, such as the BizTalk Server mapping, a simple C# script (single or multiple lines) is available as a programmable component for a single stage. In the case of using such features extensively, the paradigm takes the name imperative reactive programming.

When we use general-purpose programming languages, such as C#, we will obtain reactive programmability by adding libraries to the core base classes like Rx.NET.

The C# now available gives us the ability to use object-oriented reactive programming. This means that we can use object-oriented programming in a single reactive stage or inverse the situation by using reactive programming in a single module or class or an object-oriented application. We can use both the alternatives together in the same application too, although this last choice will make the maintainability of the code difficult for the developer.

The more pure visual reactive programming style instead gives the developer only visual components to do their job. This is what happens in the SSIS data flow diagram, although not a reactive programming language.

If, in the computational stage, we make use of functional programming or languages, such as F#, the overall paradigm will take the name functional reactive programming.

Further reading

Although this book is about reactive programming, the most transforming modules we will write will observe the object-oriented programming paradigm. This is a good thought. Simply consider the following assertion: the best programming style or language is the best only in a few conditions. Accordingly, try your programming style to the task you're facing.

Here are some suggestions:

  • Patterns of Enterprise Application Architecture, Martin Fowler, Pearson Education, Inc
  • Domain-Driven Design: Tackling Complexity in the Heart of Software, Eric Evans, Pearson Education, Inc

Summary

In this chapter, we had the opportunity to give an overall description of reactive programming frameworks and languages. Specific key concepts and designs are available for this programming paradigm.

In the next chapter, we will put into practice all such theoretic notions, writing examples in pure C#, and trying to understand all the key concepts and designs explained here.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Get to grips with the core design principles of reactive programming
  • Learn about Reactive Extensions for .NET through real-world examples
  • Improve your problem-solving ability by applying functional programming

Description

Reactive programming is an innovative programming paradigm focused on time-based problem solving. It makes your programs better-performing, easier to scale, and more reliable. Want to create fast-running applications to handle complex logics and huge datasets for financial and big-data challenges? Then you have picked up the right book! Starting with the principles of reactive programming and unveiling the power of the pull-programming world, this book is your one-stop solution to get a deep practical understanding of reactive programming techniques. You will gradually learn all about reactive extensions, programming, testing, and debugging observable sequence, and integrating events from CLR data-at-rest or events. Finally, you will dive into advanced techniques such as manipulating time in data-flow, customizing operators and providers, and exploring functional reactive programming. By the end of the book, you'll know how to apply reactive programming to solve complex problems and build efficient programs with reactive user interfaces.

Who is this book for?

If you are a .NET developer who wants to implement all the reactive programming paradigm techniques to create better and more efficient code, then this is the book for you. No prior knowledge of reactive programming is expected.

What you will learn

  • Create, manipulate, and aggregate sequences in a functional-way
  • Query observable data streams using standard LINQ query operators
  • Program reactive observers and observable collections with C#
  • Write concurrent programs with ease, scheduling actions on various workers
  • Debug, analyze, and instrument Rx functions
  • Integrate Rx with CLR events and custom scheduling
  • Learn Functional Reactive Programming with F#
Estimated delivery fee Deliver to Estonia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Jul 29, 2016
Length: 276 pages
Edition : 1st
Language : English
ISBN-13 : 9781785882883
Vendor :
Microsoft
Category :
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Estonia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Publication date : Jul 29, 2016
Length: 276 pages
Edition : 1st
Language : English
ISBN-13 : 9781785882883
Vendor :
Microsoft
Category :
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 103.97
Reactive Programming for .NET Developers
€36.99
Learning Node.js for .NET  Developers
€24.99
JavaScript for .NET Developers
€41.99
Total 103.97 Stars icon
Banner background image

Table of Contents

9 Chapters
1. First Steps Toward Reactive Programming Chevron down icon Chevron up icon
2. Reactive Programming with C# Chevron down icon Chevron up icon
3. Reactive Extension Programming Chevron down icon Chevron up icon
4. Observable Sequence Programming Chevron down icon Chevron up icon
5. Debugging Reactive Extensions Chevron down icon Chevron up icon
6. CLR Integration and Scheduling Chevron down icon Chevron up icon
7. Advanced Techniques Chevron down icon Chevron up icon
8. F# and Functional Reactive Programming Chevron down icon Chevron up icon
9. Advanced FRP and Best Practices Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
(2 Ratings)
5 star 50%
4 star 0%
3 star 50%
2 star 0%
1 star 0%
eros costas verde Oct 24, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
alot resources about Rx, this book make me open my mind to a new style of programming
Amazon Verified review Amazon
Craig E. Shea Aug 12, 2016
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
The biggest issue I have with the book is the editor did a really bad job. The authors (I know at least one of them for sure) is not a native English-speaking author. I have no issue with that--the authors' primary speaking language is what it is. However, if the book is going to be published in the English language, the editor ought to make sure that the sentences are grammatically and idiomatically correct for an English language reading audience.That is the primary job of the editor.Thank you Antonio for writing the book. Too bad the editor(s) did a very poor job of translating your thoughts to the English language in way that would make this much easier to comprehend.As far as content, the first half of the book focuses on core concepts. However, the details are nothing you probably couldn't pick up by reading the documentation. I haven't gotten to the second-half yet (it's a quick read--I just started reading this today); so when I finish the book, I'll come back and update this review to include more info on the second hald.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela