Determine if all elements fulfil a condition in a sequence with LINQ C#

Say we have the following string list:

string[] bands = { "ACDC", "Queen", "Aerosmith", "Iron Maiden", "Megadeth", "Metallica", "Cream", "Oasis", "Abba", "Blur", "Chic", "Eurythmics", "Genesis", "INXS", "Midnight Oil", "Kent", "Madness", "Manic Street Preachers"
, "Noir Desir", "The Offspring", "Pink Floyd", "Rammstein", "Red Hot Chili Peppers", "Tears for Fears"
, "Deep Purple", "KISS"};

Say we’d like to determine if all elements in the sequence fulfil a certain condition. Nothing could be easier using the All operator:

bool all = bands.All(b => b.StartsWith("A"));
Console.WriteLine(all);

This yields false as not all band names start with an A. However, their length is certainly longer than 2 characters so the below query returns true:

bool all = bands.All(b => b.Length > 2);
Console.WriteLine(all);

You can view all LINQ-related posts on this blog here.

RabbitMQ in .NET: data serialisation I

Introduction

We went through the basic messaging concepts in RabbitMQ in a previous series. You’ll find the links to all installment on this page. In this new series we’ll continue our discussion of messaging concepts in RabbitMQ. If you’re entirely new to RabbitMq then you should at least skim through the foundations as I won’t provide any detailed description of the code that was covered before.

So far we’ve kept our messages simple in order to concentrate on the key concepts: we only sent simple text messages to RabbitMQ. However, in reality we normally send objects with properties and not only text. The object needs to be serialised into a byte array so that it can be included in the message body. On the receiving end the serialised object needs to be deserialised.

We’re going to look at different ways of achieving this goal.

Most of the posts on RabbitMQ on this blog are based on the work of RabbitMQ guru Michael Stephenson.

Demo: JSON serialisation

I’m using Visual Studio 2012 for this demo but you’ll probably be fine with VS 2010 and VS 2013 as well. If you followed along the original tutorial then you can open that solution. Otherwise create a new blank solution in Visual Studio and insert a solution folder called Serialisation. Add two Console app projects to this folder: SerialisationSender and SerialisationReceiver. Add the following NuGet packages to both:

RabbitMQ new client package NuGet

Newtonsoft JSON.NET NuGet package

Add a class library called SharedObjects and add the same RabbitMq NuGet package to it as above. Insert an object called Customer:

public class Customer
{
     public string Name { get; set; }
}

Set a reference to this class library from both the Sender and the Receiver console apps. Insert another class called CommonService to the class library:

public class CommonService
{
	private string _hostName = "localhost";
	private string _userName = "guest";
	private string _password = "guest";

	public static string SerialisationQueueName = "SerialisationDemoQueue";

	public IConnection GetRabbitMqConnection()
	{
		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.HostName = _hostName;
		connectionFactory.UserName = _userName;
		connectionFactory.Password = _password;

		return connectionFactory.CreateConnection();
	}
}

Next we’ll set up the queue for this demo. Add the following code to Program.cs in the Sender app:

static void Main(string[] args)
{
	CommonService commonService = new CommonService();
	IConnection connection = commonService.GetRabbitMqConnection();
	IModel model = connection.CreateModel();
	SetupSerialisationMessageQueue(model);
}

private static void SetupSerialisationMessageQueue(IModel model)
{
	model.QueueDeclare(CommonService.SerialisationQueueName, true, false, false, null);
}

Run the Sender app and check in the RabbitMQ management console that the queue has been created. Comment out the call to SetupSerialisationMessageQueue in Main. Insert the following method to the Sender:

private static void RunSerialisationDemo(IModel model)
{
	Console.WriteLine("Enter customer name. Quit with 'q'.");
	while (true)
	{
		string customerName = Console.ReadLine();
		if (customerName.ToLower() == "q") break;
		Customer customer = new Customer() { Name = customerName };
		IBasicProperties basicProperties = model.CreateBasicProperties();
		basicProperties.SetPersistent(true);
		String jsonified = JsonConvert.SerializeObject(customer);
		byte[] customerBuffer = Encoding.UTF8.GetBytes(jsonified);
		model.BasicPublish("", CommonService.SerialisationQueueName, basicProperties, customerBuffer);
	}
}

There’s not much magic going on: we enter the customer name, construct the Customer object, build a JSON object out of it, get the byte array out of the JSON string and send it to the message queue. Add a call to this method from Main:

RunSerialisationDemo(model);

In the SerialisationReceiver add the following code to Program.cs:

static void Main(string[] args)
{
	CommonService commonService = new CommonService();
	IConnection connection = commonService.GetRabbitMqConnection();
	IModel model = connection.CreateModel();
	ReceiveSerialisationMessages(model);
}

private static void ReceiveSerialisationMessages(IModel model)
{
	model.BasicQos(0, 1, false);
	QueueingBasicConsumer consumer = new QueueingBasicConsumer(model);
	model.BasicConsume(CommonService.SerialisationQueueName, false, consumer);
	while (true)
	{
		BasicDeliverEventArgs deliveryArguments = consumer.Queue.Dequeue() as BasicDeliverEventArgs;
		String jsonified = Encoding.UTF8.GetString(deliveryArguments.Body);
		Customer customer = JsonConvert.DeserializeObject<Customer>(jsonified);
		Console.WriteLine("Pure json: {0}", jsonified);
		Console.WriteLine("Customer name: {0}", customer.Name);
		model.BasicAck(deliveryArguments.DeliveryTag, false);
	}
}

This bit of code should look very familiar to you from the foundations course: we’re listening to a specific queue and extract any incoming messages. The only new bit is that we deserialise the JSON string into a Customer object.

The demo is ready to run. Start the Sender app. Then right-click the Receiver project, select Debug, Start new Instance. You’ll have two console window up and running. Start sending customer names to the Receiver from the Sender:

Serialised message output

The same technique works for more complicated objects with multiple properties and other objects as properties.

Setting the content type

JSON is not the only message type we can send. The other two common message formats are XML and binary. No matter how you format your message, it will need to be sent to the message queue as a byte array. We’ve already seen how to serialise a JSON message. For XML you can use the following method:

private byte[] SerialiseIntoXml(Customer customer)
{
	MemoryStream memoryStream = new MemoryStream();
	XmlSerializer xmlSerialiser = new XmlSerializer(customer.GetType());
	xmlSerialiser.Serialize(memoryStream, customer);
	memoryStream.Flush();
	memoryStream.Seek(0, SeekOrigin.Begin);
        return memoryStream.GetBuffer();
}

…and to get the Customer object from a binary format you can use the following method:

private byte[] SerialiseIntoBinary(Customer customer)
{
	MemoryStream memoryStream = new MemoryStream();
	BinaryFormatter binaryFormatter = new BinaryFormatter();
	binaryFormatter.Serialize(memoryStream, customer);
	memoryStream.Flush();
	memoryStream.Seek(0, SeekOrigin.Begin);
	return memoryStream.GetBuffer();
}

Note that the Customer object must be serialisable for these to work:

[Serializable]
public class Customer
{
      public string Name { get; set; }
}

So now we can serialise our message in 3 different ways. It now makes sense to denote the content type of the message. The IBasicProperties interface has a property called ContentType where you can set the MIME type using the well-known values below:

  • JSON: application/json
  • XML: text/xml
  • Binary: application/octet-stream

Example:

[Serializable]
IBasicProperties basicProperties = model.CreateBasicProperties();
basicProperties.SetPersistent(true);
basicProperties.ContentType = "application/json";

The properties are sent along in the BasicPublish method so the MIME type is preserved.

On the client side you can read the MIME type as follows:

BasicDeliverEventArgs deliveryArguments = consumer.Queue.Dequeue() as BasicDeliverEventArgs;
string contentType = deliveryArguments.BasicProperties.ContentType;

Also, the client will need to deserialise the message. We’ve already seen how to do that in the case of the JSON format. For XML you can have the following helper method:

private Customer DeserialiseFromXml(byte[] messageBody)
{
	MemoryStream memoryStream = new MemoryStream();
	memoryStream.Write(messageBody, 0, messageBody.Length);
	memoryStream.Seek(0, SeekOrigin.Begin);
	XmlSerializer xmlSerialiser = new XmlSerializer(typeof(Customer));
	return xmlSerialiser.Deserialize(memoryStream) as Customer;
}

…and for the binary format you use something like this:

private Customer DeserialiseFromBinary(byte[] messageBody)
{
	MemoryStream memoryStream = new MemoryStream();
	memoryStream.Write(messageBody, 0, messageBody.Length);
	memoryStream.Seek(0, SeekOrigin.Begin);
	BinaryFormatter binaryFormatter = new BinaryFormatter();
	return binaryFormatter.Deserialize(memoryStream) as Customer;
}

Note that the Customer object must be shared between Sender and the Receiver for binary serialisation to work.

Denoting the type of the message

It can happen that the Receiver doesn’t know in advance what type of message is coming, i.e. if it’s a Customer, an Order, a Product etc.

You can solve this issue using the Type property of the IBasicProperties object when sending the message from the Sender. It is a string property:

IBasicProperties basicProperties = model.CreateBasicProperties();
basicProperties.SetPersistent(true);
basicProperties.ContentType = "application/json";
basicProperties.Type = "Customer";

And then you can read the type in the Receiver as follows:

BasicDeliverEventArgs deliveryArguments = consumer.Queue.Dequeue() as BasicDeliverEventArgs;
string contentType = deliveryArguments.BasicProperties.ContentType;
string objectType = deliveryArguments.BasicProperties.Type;

You are free to set the value of the Type property. You can do it in a simple way like above, but the Receiver will need to know those values. In the world of open APIs and automatic documentation generators this shouldn’t be a serious obstacle. Other solutions:

  • Fully qualified name, including the namespace, such as “SharedObjects.Customer”. This is easy to retrieve with the typeof keyword: typeof(Customer).ToString(). This approach is mostly viable within the .NET world, where both the Sender and the Receiver can work with .NET objects
  • Canonical messages where the object type is described using XSD along with the root element. This approach works best if interoperability between disparate systems is a must

We’ll look at the first option in the next post.

View the list of posts on Messaging here.

Determine if a sequence contains a certain element with LINQ C#

Say we have the following string list:

string[] bands = { "ACDC", "Queen", "Aerosmith", "Iron Maiden", "Megadeth", "Metallica", "Cream", "Oasis", "Abba", "Blur", "Chic", "Eurythmics", "Genesis", "INXS", "Midnight Oil", "Kent", "Madness", "Manic Street Preachers"
, "Noir Desir", "The Offspring", "Pink Floyd", "Rammstein", "Red Hot Chili Peppers", "Tears for Fears"
, "Deep Purple", "KISS"};

If you’d like to check if a certain string element is present in the sequence then you can use the Contains operator in LINQ:

bool contains = bands.Contains("Queen");
Console.WriteLine(contains);

This yields true as you might expect.

This was a straightforward case as .NET has a good built-in implementation of string equality. It works just as well with primitive types like int or long. .NET can determine if two integers are equal so the default version of Contains is sufficient.

It is different with your custom objects, such as this one:

public class Singer
{
	public int Id { get; set; }
	public string FirstName { get; set; }
	public string LastName { get; set; }
	public int BirthYear { get; set; }
}

Consider the following list:

IEnumerable<Singer> singers = new List<Singer>() 
			{
				new Singer(){Id = 1, FirstName = "Freddie", LastName = "Mercury", BirthYear=1964}
				, new Singer(){Id = 2, FirstName = "Elvis", LastName = "Presley", BirthYear = 1954}
				, new Singer(){Id = 3, FirstName = "Chuck", LastName = "Berry", BirthYear = 1954}
				, new Singer(){Id = 4, FirstName = "Ray", LastName = "Charles", BirthYear = 1950}
				, new Singer(){Id = 5, FirstName = "David", LastName = "Bowie", BirthYear = 1964}
			};

…and the following code:

Singer s = new Singer() { Id = 2, FirstName = "Elvis", LastName = "Presley", BirthYear = 1954 };
bool containsSinger = singers.Contains(s);
Console.WriteLine(containsSinger);

This will of course yield false as equality is based on references and there’s no element in the sequence with the same reference as “s”. In this case we can use the overloaded version of Contains where you can supply an equality comparer:

public class DefaultSingerComparer : IEqualityComparer<Singer>
{
	public bool Equals(Singer x, Singer y)
	{
		return x.Id == y.Id;
	}

	public int GetHashCode(Singer obj)
	{
		return obj.Id.GetHashCode();
	}
}

So equality is based on the ID. We can rewrite our query as follows:

Singer s = new Singer() { Id = 2, FirstName = "Elvis", LastName = "Presley", BirthYear = 1954 };
bool containsSinger = singers.Contains(s, new DefaultSingerComparer());
Console.WriteLine(containsSinger);

…which yields true.

You can view all LINQ-related posts on this blog here.

Reversing a sequence using the Reverse operator in .NET LINQ

Reversing the order of a sequence with LINQ is extremely simple: just use the Reverse() operator.

Example data structure:

string[] bands = { "ACDC", "Queen", "Aerosmith", "Iron Maiden", "Megadeth", "Metallica", "Cream", "Oasis", "Abba", "Blur", "Chic", "Eurythmics", "Genesis", "INXS", "Midnight Oil", "Kent", "Madness", "Manic Street Preachers"						 , "Noir Desir", "The Offspring", "Pink Floyd", "Rammstein", "Red Hot Chili Peppers", "Tears for Fears"						 , "Deep Purple", "KISS"};

You can use the Reverse operator as follows:

IEnumerable<string> bandsReversed = bands.Reverse();
foreach (string item in bandsReversed)
{
	Console.WriteLine(item);
}

…which will print the above array in reverse order, i.e. starting with KISS and finishing with ACDC.

You can view all LINQ-related posts on this blog here.

Creating a grouped join on two sequences using the LINQ GroupJoin operator

The GroupJoin operator is very similar to the Join operator. I won’t repeat the things we discussed there, so I recommend you read that post first if you’re not familiar with that operator.

With GroupJoin we can not only join elements in two sequences but group them at the same time.

GroupJoin has the same signature as Join with one exception. The result selector in Join has the following type:

Func<TOuter, TInner, TResult>

…whereas the result selector in GroupJoin looks as follows:

Func<TOuter, IEnumerable<TInner>, TResult>

We have the following sample data structure:

public class Singer
{
	public int Id { get; set; }
	public string FirstName { get; set; }
	public string LastName { get; set; }
}

public class Concert
{
	public int SingerId { get; set; }
	public int ConcertCount { get; set; }
	public int Year { get; set; }
}

public static IEnumerable<Singer> GetSingers()
{
	return new List<Singer>() 
	{
		new Singer(){Id = 1, FirstName = "Freddie", LastName = "Mercury"} 
		, new Singer(){Id = 2, FirstName = "Elvis", LastName = "Presley"}
		, new Singer(){Id = 3, FirstName = "Chuck", LastName = "Berry"}
		, new Singer(){Id = 4, FirstName = "Ray", LastName = "Charles"}
		, new Singer(){Id = 5, FirstName = "David", LastName = "Bowie"}
	};
}

public static IEnumerable<Concert> GetConcerts()
{
	return new List<Concert>()
	{
		new Concert(){SingerId = 1, ConcertCount = 53, Year = 1979}
		, new Concert(){SingerId = 1, ConcertCount = 74, Year = 1980}
		, new Concert(){SingerId = 1, ConcertCount = 38, Year = 1981}
		, new Concert(){SingerId = 2, ConcertCount = 43, Year = 1970}
		, new Concert(){SingerId = 2, ConcertCount = 64, Year = 1968}
		, new Concert(){SingerId = 3, ConcertCount = 32, Year = 1960}
		, new Concert(){SingerId = 3, ConcertCount = 51, Year = 1961}
		, new Concert(){SingerId = 3, ConcertCount = 95, Year = 1962}
		, new Concert(){SingerId = 4, ConcertCount = 42, Year = 1950}
		, new Concert(){SingerId = 4, ConcertCount = 12, Year = 1951}
		, new Concert(){SingerId = 5, ConcertCount = 53, Year = 1983}
	};
}

In the example on Join we joined the single elements in the singers list with the concert list based on the singer ids. We will do the same here but at the same time we want to read the total number of concerts for each singer. The following query will do just that:

IEnumerable<Singer> singers = DemoCollections.GetSingers();
IEnumerable<Concert> concerts = DemoCollections.GetConcerts();

var singerConcerts = singers.GroupJoin(concerts, s => s.Id, c => c.SingerId, (s, co) => new
{
	Id = s.Id
	, SingerName = string.Concat(s.FirstName, " ", s.LastName)
	, ConcertCount = co.Sum(c => c.ConcertCount)
});

foreach (var res in singerConcerts)
{
	Console.WriteLine(string.Concat(res.Id, ": ", res.SingerName, ", ", res.ConcertCount));
}

GroupJoin operator output

Each type in the lambda expressions will be inferred by the compiler:

  • ‘s’ is of type Singer for the outer selector
  • ‘c’ is of type Concert for the inner selector
  • ‘co’ is type IEnumerable of Concert which will be used for the grouping function, Sum in this case

Just like the Join operator, GroupJoin can also accept an IEqualityComparer of TKey in case the comparison key requires some special treatment. In the above example only integers are compared so there’s no need for anything extra.

You can view all LINQ-related posts on this blog here.

Introduction to WebSockets with SignalR in .NET Part 5: dependency injection in Hub

Introduction

We’ve now gone through the basics of SignalR. We’ve looked at a messaging project and a primitive, but working stock ticker. Actually most of the work is put on the client in form of JavaScript code. The WebSockets specific server side code is not too complex and follows standard C# coding syntax.

However, the relative server side simplicity doesn’t mean that our code shouldn’t follow good software engineering principles. I mean principles such as SOLID, with special subjective weight given to my favourite, the letter ‘D‘.

You’ll recall from the previous post that the stock prices were retrieved from a concrete StockService class, an instance of which was created within the body of StartStockMonitoring(). The goal now is to clean up that code so that the stock prices are retrieved from an interface instead of a concrete class. The interface should then be a parameter of the ResultsHub constructor.

We’ll use StructureMap to inject the dependency into ResultsHub.cs.

Demo

I’ll use two sources from StackOverflow to solve the problem:

Let’s start by creating the abstraction. Add the following interface to the Stocks folder:

public interface IStockService
{
	dynamic GetStockPrices();
}

Then modify the StockService declaration so that it implements the abstraction:

public class StockService : IStockService

Change the ResultsHub constructor to accept the interface dependency:

private readonly IStockService _stockService;

public ResultsHub(IStockService stockService)
{
	if (stockService == null) throw new ArgumentNullException("StockService");
	_stockService = stockService;
	StartStockMonitoring();
}

Make sure you refer to the private field in the Task body of StartStockMonitoring:

Task stockMonitoringTask = Task.Factory.StartNew(async () =>
				{					
					while(true)
					{
						dynamic stockPriceCollection = _stockService.GetStockPrices();
						Clients.All.newStockPrices(stockPriceCollection);
						await Task.Delay(5000);
					}
				}, TaskCreationOptions.LongRunning);

Next, create an interface for ResultsHub in the Stocks folder:

public interface IResultsHub
{
	void Hello();
	void SendMessage(String message);
}

…and have ResultsHub implement it:

public class ResultsHub : Hub, IResultsHub

Next import the StructureMap NuGet package:

StructureMap NuGet package

We’ll need a custom HubActivator to find the implementation of IResultsHub through StructureMap. Add the following class to the solution:

public class HubActivator : IHubActivator
{
	private readonly IContainer container;

	public HubActivator(IContainer container)
	{
		this.container = container;
	}

	public IHub Create(HubDescriptor descriptor)
	{
		return (IHub)container.GetInstance(descriptor.HubType);
	}
}

IContainer is located in the StructureMap namespace.

Next insert the following class that will initialise the StructureMap container:

public static class IoC
{
	public static IContainer Initialise()
	{
		ObjectFactory.Initialize(x =>
			{
				x.Scan(scan =>
					{
						scan.AssemblyContainingType<IResultsHub>();
						scan.WithDefaultConventions();
					});
			});
		return ObjectFactory.Container;
	}
}

The last step is to register our hub activator when the application starts. Add the following code to Application_Start() in Global.asax.cs:

IContainer container = IoC.Initialise();
GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => new HubActivator(container));

That’s it actually. Set a breakpoint within the ResultsHub constructor and start the application. If all goes well then code execution should stop at the breakpoint. Inspect the incoming stockService parameter. If it’s null then something’s gone wrong but it shouldn’t be. Let the code execution continue and you’ll see that it works as before except that we’ve come a good step closer to loosely coupled code.

Read the finishing post in this series here.

View the list of posts on Messaging here.

Selecting a subset of elements in LINQ C# with the Take operator

The Take extension method in LINQ returns a specified number of elements from a sequence. Its usage is very simple. Consider the following data collection:

string[] bands = { "ACDC", "Queen", "Aerosmith", "Iron Maiden", "Megadeth", "Metallica", "Cream", "Oasis", "Abba", "Blur", "Chic", "Eurythmics", "Genesis", "INXS", "Midnight Oil", "Kent", "Madness", "Manic Street Preachers"
, "Noir Desir", "The Offspring", "Pink Floyd", "Rammstein", "Red Hot Chili Peppers", "Tears for Fears"
, "Deep Purple", "KISS"};

The following query returns the first 10 elements from the collection:

IEnumerable<String> topItems = bands.Take(10);
foreach (string item in topItems)
{
	Console.WriteLine(item);
}

…whicl will print the array items 0-9.

You’re free to combine the Take operator with other operators, such as Select. Example:

var anonymous = bands.Take(10).Select(b => new { Name = b, Length = b.Length });
foreach (var anon in anonymous)
{
	Console.WriteLine("Band name: {0}, length: {1}", anon.Name, anon.Length);
}

The query takes the top 10 items and runs the Select operator only on those 10 items, not the entire collection. Here’s the output:

Take operator output

You can view all LINQ-related posts on this blog here.

Joining two collections using the C# Concat LINQ operator

What if you want to join two sequences of the same type into one sequence? It couldn’t be easier with the LINQ Concat() operator.

Data structure:

string[] bands = { "ACDC", "Queen", "Aerosmith", "Iron Maiden", "Megadeth", "Metallica", "Cream", "Oasis", "Abba", "Blur", "Chic", "Eurythmics", "Genesis", "INXS", "Midnight Oil", "Kent", "Madness", "Manic Street Preachers"
, "Noir Desir", "The Offspring", "Pink Floyd", "Rammstein", "Red Hot Chili Peppers", "Tears for Fears"
, "Deep Purple", "KISS"};

Say you’d like to get the first and the last 5 elements of this sequence and build a single sequence. The following LINQ statement will do the trick:

IEnumerable<string> selectedItems = bands.Take(5).Concat(bands.Reverse().Take(5));
foreach (string item in selectedItems)
{
	Console.WriteLine(item);
}

Concat operator output

You can view all LINQ-related posts on this blog here.

Introduction to WebSockets with SignalR in .NET Part 4: stock price ticker

Introduction

In the last post we saw the first basic, yet complete example of SignalR in action. We demonstrated the core functionality of a messaging application where messages are shown on screen in real time.

We’re now ready to implement the demo that I promised before: update a stock price in real time and propagate the changes to all listening browsers.

We’ll build on the sample project we’ve been working on so far in this series, so have it open and let’s get into it!

Demo: server side

Add a folder to the solution called Stocks. Add a new class called Stock:

public class Stock
{
	public Stock(String name)
	{
		Name = name;
	}

	public string Name { get; set; }
	public double CurrentPrice 
	{
		get
		{
			Random random = new Random();
			return random.NextDouble() * 10.0;
		}
	}
}

We need a stock name in the constructor. We’ll simply randomize the stock price using Random.NextDouble(). In reality it will be some proper repository that does this but again, we’ll keep the example simple.

Next add a new class called StockService which will wrap stock-related methods.

Note that such service classes should be hidden behind an interface and injected into the consuming class to avoid tight coupling. However, for this sample we’ll ignore all such “noise” and concentrate on the subject matter. If you’re not sure what I’m on about then read about dependency inversion here. The next post on SignalR will explore dependency injection.

StockService takes the following form:

public class StockService
{
	private List<Stock> _stocks;

	public StockService()
	{
		_stocks = new List<Stock>();
		_stocks.Add(new Stock("GreatCompany"));
		_stocks.Add(new Stock("NiceCompany"));
		_stocks.Add(new Stock("EvilCompany"));
	}

	public dynamic GetStockPrices()
	{
		return _stocks.Select(s => new { name = s.Name, price = s.CurrentPrice });
	}
}

We maintain a list of companies whose stocks are monitored. We return an anonymous class for each Stock in the list, hence the dynamic keyword.

We’ll read these values from our ResultsHub hub. We’ll need to constantly monitor the stock prices in a loop on a separate thread so that it doesn’t block all other code. This calls for a Task from the Task Parallel Library. If you don’t know what Tasks are then check out the first couple of posts on TPL here, a basic knowledge will suffice. We’ll need to start monitoring the prices as soon as someone opens the page in a browser. We can start the process directly from the hub constructor:

public ResultsHub()
{
	StartStockMonitoring();
}

private void StartStockMonitoring()
{
	
}

Here’s the complete StartStockMonitoring method:

private void StartStockMonitoring()
{
	Task stockMonitoringTask = Task.Factory.StartNew(async () =>
		{
			StockService stockService = new StockService();
			while(true)
			{
				dynamic stockPriceCollection = stockService.GetStockPrices();
				Clients.All.newStockPrices(stockPriceCollection);
				await Task.Delay(5000);
			}
		}, TaskCreationOptions.LongRunning);
}

We start a task that instantiates a stock service and starts an infinite loop. We retrieve the stock prices and inform all clients through a newStockPrices JavaScript method and pass in the stock prices dynamic object. Then we pause the loop for 5 seconds using Task.Delay. Task.Delay returns an awaitable task so we need the await keyword. In order for that to take effect through we’ll need to decorate the lambda expression with async. You’ve never heard of await and async? Start here. Finally, we notify the task scheduler in the task constructor that this will be a long running process.

Demo: client side

Let’s extend our GUI and results.js to show the stock prices in real time. We’ll use a similar approach as we had in case of the messaging demo: knockout.js with a view-model. Add the following code to results.js:

resultsHub.client.newStockPrices = function (stockPrices) {
     viewModel.addStockPrices(stockPrices);
}

…which will be the JS function that’s called from ResultsHub.StartStockMonitoring. We’ll complete the addStockPrices later, we need some building blocks first. We’ll need a new custom JS object to store a single stock. Add the following constructor function to results.js:

var stock = function (stockName, price) {
        this.stockName = stockName;
        this.price = price;
};

Also, we need a new property in the messageModel constructor function to store the stock prices in an array:

var messageModel = function () {
        this.registeredMessage = ko.observable(""),
        this.registeredMessageList = ko.observableArray(),
        this.stockPrices = ko.observableArray()
    };

Add the following function property to messageModel.prototype:

addStockPrices: function (updatedStockPrices) {
            var self = this;     

            $.each(updatedStockPrices, function (index, updatedStockPrice) {
                var stockEntry = new stock(updatedStockPrice.name, updatedStockPrice.price);
                self.stockPrices.push(stockEntry);                
            });
}

We simply add each update to the observable stockPrices array. updatedStockPrice.name and updatedStockPrice.price come from our dynamic function in StockService:

public dynamic GetStockPrices()
{
	return _stocks.Select(s => new { name = s.Name, price = s.CurrentPrice });
}

We just need some extra HTML in Index.cshtml:

<div data-bind="foreach:stockPrices">
    <p><span data-bind="text:stockName"></span>: <span data-bind="text:price"></span></p>
</div>

The stockName and price properties in the text bindings come from the stock object in results.js.

This should be it. Start the application and you’ll see the list of stocks and their most recent prices coming in from the server in a textual form.

View the next part of this series here.

View the list of posts on Messaging here.

Finding the set difference between two sequences using the LINQ Except operator

Say you have the following two sequences:

string[] first = new string[] {"hello", "hi", "good evening", "good day", "good morning", "goodbye" };
string[] second = new string[] {"whatsup", "how are you", "hello", "bye", "hi"};

If you’d like to find the values that only figure in “first” then it’s easy to achieve using the LINQ Except operator:

IEnumerable<string> except = first.Except(second);
foreach (string value in except)
{
	Console.WriteLine(value);
}

The “except” variable will include “good evening”, “good day”, “good morning”, “goodbye” as “hello”, “hi” also figure in “second”.

The Except operator uses a comparer to determine whether two elements are equal. In this case .NET has a built-in default comparer to compare strings so you didn’t have to implement any special comparer. However, if you have custom objects in the two arrays then the default object reference comparer won’t be enough:

public class Singer
{
	public int Id { get; set; }
	public string FirstName { get; set; }
	public string LastName { get; set; }
}

IEnumerable<Singer> singersA = new List<Singer>() 
{
	new Singer(){Id = 1, FirstName = "Freddie", LastName = "Mercury"} 
	, new Singer(){Id = 2, FirstName = "Elvis", LastName = "Presley"}
	, new Singer(){Id = 3, FirstName = "Chuck", LastName = "Berry"}

};

IEnumerable<Singer> singersB = new List<Singer>() 
{
	new Singer(){Id = 1, FirstName = "Freddie", LastName = "Mercury"} 
	, new Singer(){Id = 2, FirstName = "Elvis", LastName = "Presley"}
	, new Singer(){Id = 4, FirstName = "Ray", LastName = "Charles"}
	, new Singer(){Id = 5, FirstName = "David", LastName = "Bowie"}
};

IEnumerable<Singer> singersDiff = singersA.Except(singersB);
foreach (Singer s in singersDiff)
{
	Console.WriteLine(s.Id);
}

The singersDiff sequence will include everything from singersA of course as each object is different as far as their references are concerned. This is where the second prototype of the operator enters the scene where you can define your own comparison function:

public class DefaultSingerComparer : IEqualityComparer<Singer>
{
	public bool Equals(Singer x, Singer y)
	{
		return x.Id == y.Id;
	}

	public int GetHashCode(Singer obj)
	{
		return obj.Id.GetHashCode();
	}
}

So we say that singerA == singerB if their IDs are equal. You can use this comparer as follows:

IEnumerable<Singer> singersDiff = singersA.Except(singersB, new DefaultSingerComparer());
foreach (Singer s in singersDiff)
{
	Console.WriteLine(s.Id);
}

singersDiff will now correctly include singer #3 only.

You can view all LINQ-related posts on this blog here.

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

ARCHIVED: Bite-size insight on Cyber Security for the not too technical.