Real time data processing using Web Api, TPL Dataflow, SignalR and AngularJS

TPL Dataflow Library provides a foundation for message passing and parallelizing CPU-intensive and I/O-intensive applications that have high throughput and low latency.

we want to just write the code, and the way we structure it results in no synchronization issues.  So  we don’t have to think about synchronization. In this world each object has its own private thread of execution, and only ever manipulates its own internal state.

Instead of one single thread executing through many objects by calling object methods, objects send asynchronous messages to each other.

If the object is busy processing a previous message, the message is queued. When the object is no longer busy it then processes the next message.
Fundamentally, if each object only has one thread of execution, then updating its own internal state is perfectly safe.

Blocks are essentially a message source, target, or both. In addition to receiving and sending messages, a block represents an element of concurrency for processing the messages it receives.

Multiple blocks are linked together to produce networks of blocks. Messages are then posted asynchronously into the network for processing.

Consider the following use case.  Several orders  are extracted from a source, The data contained in each order need to be transformed into a orderDetail object ready to be sent to the  Sales web service as a SalesOrderDetail object.


The  process could be structured into a series of blocks, where each block is responsible for doing some part of the overall processing.

We want to improve system performance but also we want to monitor the process in real time.

To achieve this goal, we suggest to build a distributed architecture consisting of a REST web server ( ASP.NET WEB API,  SIGNALR),  a WEB client (ASP.NET MVC and Angular JS ) and a web service that processes files ( WCF or Other).

To follow this tutorial, you must undertand ASP.NET WEB API , SIGNALR and TPL Dataflow.


  • Monitoring Client   : ASP.NET MVC and AngularJS
  • Processing Server : TPL DataFlow

To Build our Hub Server, we will use ASP.NET Web API because clients must connect to the hub by uploading json data

For more information about SIGNALR please take a look at

So, let Create an ASP.NET WEB API Project  as follow :

  • install Microsoft ASP.NET SignalR

Image sans titre5

Lets define a HubName dashboads , to get notified, clients (web browsers, mobiles, desktop app, ……) must connect to the defined Hub

Image sans titre1

Image sans titre2

Lets define  a ApiController (DashboardController)  derived from SignalRBase and 2 action PostProcessor  and PostSalesOrderDetailEntity

SignalRBase implement IHub and allow us to access our Hub inside DashboardController.

Image sans titre3

Image sans titre4

We use SignalR  as it allows bi-directional communication between server and client. Servers can now push content to connected clients instantly as it becomes available and supports Web Sockets.

  • Hub.Clients.All.LoadBalance(item) ==>  Send message to all connected clients (Notify all connected client to invoke LoadBalance function of the Hub)
  • Hub.Clients.Client(id).LoadBalance(item) ==> Send Message to a specific client.
  • Hub.Clients.Group(groupId).LoadBalance(item) ==> Send Message to all clients connected to a specific group.

When Server is invoked, Hub.Clients.All.LoadBalance(item) ( where item is Processor), data is pushed to Hub and be available for clients as follow


I will implement the processing server using TPL Dataflow

There are several blocks like ActionBlock<TInput>, ActionBlock<TInput>,  BroadcastBlock<T>, BufferBlock<T> etc….

So create a class library project and add the following :

Image sans titre6

Image sans titre8

  • _blockConfiguration provide options to configure Dataflow network.  Here we configure our block to be parallelized using the number of processor available in the current machine (MaxDegreeOfParallelism = Environment.ProcessorCount)
  • _bufferBlock has the responsibility to extract orders from the source  as they arrive
  • _receptorBlockOne , _receptorBlockTwo and _receptorBlockThree has the responsibility to load balance fetched orders and calculate OrderDetails from Orders
  • _transformBlockCalculateSalesOrderDetailhas responsability to calculate SalesOrderDetails from OrderDetails
  • _loggerBlock  has responsability to log informations

For better performance , we want to load balance our process. So our next step is to create 3 load balanced receptors,  if _receptorBlockOne is busy, _receptorBlockTwo or _receptorBlockThee will process the item,… ReceptorBlockOne, ReceptorBlockTwo and ReceptorBlockThree are blocks. So, if a message is refused by one block, the next linked block will be offered the message. If all blocks refuse the message, the first block to become available to process the message will do so. To achieve this goal, we have to make a block non-greedy, simply set the queue length to 1.

Image sans titre9

Lets define a flowComplete variable so as to propagate completion and faulting notification  automatically.

Image sans titre10

Now, its time to build our network by linking our Dataflow blocks

Image sans titre 11

The following example shows the complete code for this walkthrough.

1 3 4 5 6 7


Lets create a project and add the following

Image sans titre1

Reference the following packages

Image sans titre11

Image sans titre12 Image sans titre13

Define a module

Image sans titre2

Define an app function

Image sans titre3

Define a dashboardSvc service

Image sans titre4

Define a dashboardCtrl controller

Image sans titre5 Image sans titre6

Define an Index view

Image sans titre7 Image sans titre8 Image sans titre9

The result in action


I hope this post will help you.

Sample code is available here   DataflowSignalrAngularDemo




I’m a .NET Architect and Technical Expert skills located in Paris (FRANCE). The purpose of this blog is mainly to post general .NET tips and tricks,

Leave a Reply

Your email address will not be published. Required fields are marked *