Events, delegates and lambdas in .NET C# part 6: other scenarios

Introduction

So far in this series we’ve seen the basics of events, delegates and lambdas. We’ve looked at examples of how to define these elements and use them in code.

It’s now time for us to look at some other simulated scenarios where you can use these language elements. In particular we’ll look at the following:

  • Mediator pattern with delegates
  • Asynchronous delegate invocation

Communication across components

Imagine a scenario where you have a dynamic GUI of a Windows application. The components – widgets – can be loaded here and there and they are independent of each other to allow for loose coupling. At the same time they should be able to communicate with each other.

This scenario can be generalised: imagine independent objects that don’t know about other objects but still want to communicate with them in case they are present.

This is a perfect scenario for events and delegates and a pattern called the Mediator pattern. If you don’t know what a mediator is then make sure to read that introduction where the pattern is demonstrated without using events and delegates. With independent components we’ll need a Mediator that acts as a glue for those components. They will only know about the Mediator but not the other objects they are indirectly communicating with.

An additional pattern that is useful in this scenario is the Singleton pattern. If you don’t know what it means then skim through that article to get the basics. The purpose of the singleton in this case is to have only one Mediator class in memory. Otherwise the independent components may reference different mediators.

Note that this post concentrates on the role of delegates and events. If you’d like to extend this example so that it better follows SOLID and abstractions then look through blog entries in the Architecture and patterns section.

Open the project we’ve been working on in this series and add a new C# library called ComponentsMediator. Add a new class to it called Mediator which will be responsible for the communication between the independent components.

Add the following elements to adhere to the singleton pattern. We’ll employ a simple version of the pattern. Read the referenced article to see what some of the other possible solutions are.

private static readonly Mediator _instance = new Mediator();

private Mediator() { }
public static Mediator Instance
{
        get
	{
		return _instance;
	}
}

We’ll simulate the scenario where the user selects a product in a drop down list. We want to update the screen accordingly. Add the following Product class to the project:

public class Product
{
	public int Id { get; set; }
	public string Name { get; set; }
	public DateTime Registered { get; set; }
	public int OnStock { get; set; }
}

Return to Mediator.cs and add the following event handler to the Mediator:

public event EventHandler<ProductChangedEventArgs> ProductChanged;

…where ProductChangedEventArgs looks as follows:

public class ProductChangedEventArgs : EventArgs
{
	public Product Product { get; set; }
}

We’ll raise the event in the following method:

public void OnProductChanged(object sender, Product product)
{
	if (ProductChanged != null)
	{
		ProductChanged(sender, new ProductChangedEventArgs() { Product = product });
	}
}

By allowing the sender to be passed in we show that the original event raiser was an object different from the Mediator. Otherwise all products would “think” that the Mediator raised the event which is not entirely true. Keep in mind that the mediator is only an errrm…, well, a mediator. It mediates between independent objects. We need to see if there’s any listener by checking if ProductChanged is null.

Let’s add a component that will initiate the product selection change. You can think of this object as a combo box where the users can select products:

public class ProductChangeInitiator
{
	public ProductChangeInitiator(int selectedProductId)
	{
		SelectedProductId = selectedProductId;			
	}

	public int SelectedProductId { get; set; }

}

Add another class to the library called ProductChangeSimulation and a method called SimulateProductChange:

public class ProductChangeSimulation
{
        private List<Product> _allProducts = new List<Product>()
	{
		new Product(){Name = "FirstProduct", Id = 1, Registered = DateTime.Now.AddDays(-1), OnStock = 456}
		, new Product(){Name = "SecondProduct", Id = 2, Registered = DateTime.Now.AddDays(-2), OnStock = 123}
		, new Product(){Name = "ThirdProduct", Id = 3, Registered = DateTime.Now.AddDays(-3), OnStock = 987}
		, new Product(){Name = "FourthProduct", Id = 4, Registered = DateTime.Now.AddDays(-4), OnStock = 432}
		, new Product(){Name = "FifthProduct", Id = 5, Registered = DateTime.Now.AddDays(-5), OnStock = 745}
		, new Product(){Name = "SixthProduct", Id = 6, Registered = DateTime.Now.AddDays(-6), OnStock = 456}
	};

	public void SimulateProductChange(ProductChangeInitiator changeInitiator)
	{
		Product selectedProduct = (from p in _allProducts where p.Id == changeInitiator.SelectedProductId select p).FirstOrDefault();
		Mediator.Instance.OnProductChanged(changeInitiator, selectedProduct);
	}
}

We maintain a list of products in a private variable. We let the product change initiator to be passed into the method. We then call the OnProductChanged event handler of the mediator by passing the changeInitiator as the original sender and the selected product.

We now have the components ready in order to raise the event and pass in the necessary parameters. We’ll now need a listener. Add a new class called Warehouse:

public class Warehouse
{
	public Warehouse()
	{
		Mediator.Instance.ProductChanged += (s, e) => { SaveChangesInRepository(e.Product); };
	}

	private void SaveChangesInRepository(Product product)
	{
		Console.WriteLine("About to save the changes for product {0}", product.Name);
	}
}

We subscribe to the ProductChanged event of the mediator where the initiator of the event is unknown to Warehouse. It could be any component in reality: a customer, an e-commerce site, a physical shop, whatever. The Warehouse object won’t care. It only wants to know if there was a change so that it can go on with its job. As you see we declared the event subscription with a lambda.

Add a reference from the main project to the ComponentsMediator library. We can connect the pieces from Program.Main as follows:

ProductChangeInitiator initiator = new ProductChangeInitiator(2);
Warehouse warehouse = new Warehouse();
ProductChangeSimulation simulation = new ProductChangeSimulation();
simulation.SimulateProductChange(initiator);

We simulate the product id #2 was selected and start the simulation. You’ll see that Warehouse correctly displays the message in the console.

Let’s add another listener to the library project. Let’s say that the company CEO is a control freak and wants to be notified of all product changes:

public class CEO
{
	public CEO()
	{
		Mediator.Instance.ProductChanged += (s, e) => 
		{ 
			Console.WriteLine("This is the CEO speaking. Well done for selling {0}", e.Product.Name); 
		};
	}
}

Extend the code in Main as follows:

ProductChangeInitiator initiator = new ProductChangeInitiator(2);
Warehouse warehouse = new Warehouse();
CEO ceo = new CEO();
ProductChangeSimulation simulation = new ProductChangeSimulation();
simulation.SimulateProductChange(initiator);

You’ll see that the CEO is very happy now. We effortlessly added another listener to the product change. The CEO, Warehouse and ProductChangeInitiator objects don’t know about each other. This ensures that the components remain loosely coupled. The listeners won’t care where the notification is coming from, they are only connected to the mediator.

Asynchronous delegates

Let’s look at how asynchronous operations can be applied to delegates. Insert a new C# library to the project called AsyncDelegates. Insert a new class called AsynchronousProcessSimulation. Imagine that we start a long process and want to be notified of the progress made. Insert the following method that represents our lengthy process:

private void DoProgress(int maxValue)
{
	for (int i = 0; i <= maxValue; i++)
	{
		Console.WriteLine("Time : {0}", i);
		Thread.Sleep(50);
	}
}

We want to use a delegate to wire the information to the DoProgress method. We’ll do it with a private delegate:

private delegate void ShowProgressDelegate(int status);

Insert the following public entry point that initiates the delegate:

public void StartReporting()
{
	ShowProgressDelegate progressDelegate = new ShowProgressDelegate(DoProgress);
}

Let’s say that we want to invoke this delegate asynchronously. Delegates have a built-in method called BeginInvoke which comes in very handy. It will spin up a separate thread that will call into DoProgress. We can pass in the value for the maxValue parameter, a callback function and an additional object input which will be null in this example. We don’t need a callback either. Add the following async call to StartReporting:

progressDelegate.BeginInvoke(500, null, null);
Console.WriteLine("Finishing the StartReporting method.");

Insert a reference to this project from the main project. You can test the async delegate as follows:

AsynchronousProcessSimulation asyncSimulation = new AsynchronousProcessSimulation();
asyncSimulation.StartReporting();

You’ll see that “Finishing the StartReporting method.” is printed in the console after the delegate has been invoked on a different thread proving the point that BeginInvoke did in fact spawn up a new thread. The lengthy operation just keeps running in the background.

This post finishes this series on delegates and events. I hope you have learned some new stuff that you can use in your own project.

Wait for a single Task in .NET C#: the Wait() method

Waiting for a single Task to finish is as easy as calling the Wait() method or one of its overloaded versions:

Wait();
Wait(CancellationToken);
Wait(int);
Wait(TimeSpan);
Wait(int, CancellationToken);

In short from top to bottom:

  • Wait until the Task completes, is cancelled or throws an exception
  • Wait until the cancellation token is cancelled or the task completes, is cancelled or throws an exception
  • Wait for ‘int’ amount of milliseconds to pass OR for the task to complete, be cancelled or throw an exception, whichever happens first
  • Wait for ‘TimeSpan’ amount of time to pass OR for the task to complete, be cancelled or throw an exception, whichever happens first
  • Wait for ‘int’ amount of milliseconds to pass, for the cancellation token to be cancelled, OR for the task to complete, be cancelled or throw an exception, whichever happens first

Example:

Construct the cancellation token:

CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;

Start a task:

Task task = Task.Factory.StartNew(() =>
{
	for (int i = 0; i < 10; i++)
	{
		cancellationToken.ThrowIfCancellationRequested();
		Console.WriteLine(i);
		cancellationToken.WaitHandle.WaitOne(1000);
	}
}, cancellationToken);

We can then wait for the task to complete:

task.Wait();

If we are impatient then we specify a maximum amount of milliseconds for the task to complete otherwise it is abandoned:

task.Wait(2000);

The other overloads work in a similar manner.

View the list of posts on the Task Parallel Library here.

Events, delegates and lambdas in .NET C# part 5: lambda, Func, Action

Introduction

In this post we’ll continue our discussion by diving into the following topics:

  • Lambdas
  • Func of T,TResult
  • Action of T

Lambdas

Lambdas fit very well into the topic of events and delegates. We touched upon anonymous methods at the end of the previous post:

superman.WorldSavingCompleted += delegate(object sender, WorldSavingCompletedEventArgs e)
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero has saved the world! Name: ").Append(e.Saviour)
		.Append(", time spent saving the world: ").Append(e.HoursItTookToSaveWorld).Append(", message from the superhero: ")
		.Append(e.MessageFromSaviour);
	Console.WriteLine(superHeroMessageBuilder.ToString());
};

Anonymous methods are a good way to get going with lambdas as they have a similar syntax. However, lambdas are more concise. The following is the lambda equivalent of the anonymous method:

superman.WorldSavingCompleted += (s, e) => 
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero has saved the world! Name: ").Append(e.Saviour)
		.Append(", time spent saving the world: ").Append(e.HoursItTookToSaveWorld).Append(", message from the superhero: ")
		.Append(e.MessageFromSaviour);
	Console.WriteLine(superHeroMessageBuilder.ToString());
};

In case the method body is a single statement then you can leave out the curly braces:

superman.WorldSavingCompleted += (s, e) => Console.WriteLine("World saved by " + e.Saviour);

Note how you can access the properties of the event args without having to declare the exact type in the parameter list.

The structure of a lambda expression is the following:

  • Method parameters, in this case (s, e). If there are no input params then this simply becomes (). The compiler will infer the parameter types from the delegate signature. That’s how you could access the Saviour property of the WorldSavingCompletedEventArgs parameter
  • The parameters are followed by the lambda operator ‘=>’. It separates the input parameters from the method body
  • The method body: the parameters defined within the parenthesis will be passed into this inline method

Lambdas with custom delegates

Open the console application we’ve been working on in this series. Add a new class called ProcessIntegers:

public class ProcessIntegers
{
	public void DoAction(int firstInteger, int secondInteger)
	{
	}
}

At first this doesn’t look very clever: we don’t know how the integers will be processed and the method doesn’t return anything. However, by now we know that with delegates and events we can return multiple values from a void method. The goal here is to generalise the way two integers are handled: multiply them, add them etc. Instead of guessing what a client may want to do with the integers and writing 10 methods we’ll let the client define the operation.

In Program.cs insert the following custom delegate:

public delegate int IntegerOperationDelegate(int first, int second);

So it takes two integers and returns an integer. Let’s extend the DoAction method so that it accepts a delegate of this type:

public void DoAction(int firstInteger, int secondInteger, IntegerOperationDelegate del)
{
	int result = del(firstInteger, secondInteger);
	Console.WriteLine(result);
}

So we invoke the delegate in the method body and print out the result. The method allows the caller to pass in a custom delegate so that the DoAction method doesn’t have to be hard coded as far as processing the two integers are concerned. The DoAction method will have no knowledge about the exact delegate passed in which allows for the construction of loosely coupled classes. You can call DoAction from Main using lambdas. Here’s the first integer processor:

IntegerOperationDelegate addIntegersDelegate = (f, s) => f + s;

Looks weird if you see this for the first time, right? You’ll now recognise the input parameters and the lambda operator. Recall that the signature must match the delegate signature hence the (f, s) bit which stand for the first and second integers. The ‘f + s’ bit looks strange as there’s no return statement. It is added by the compiler for you in case there are no curly braces. It is inferred from the delegate signature that you’d like to add two numbers and return the result. A more obvious way of declaring this delegate is the following:

IntegerOperationDelegate addIntegersDelegate = (f, s) => { return f + s; };

Let’s add a couple more delegates:

IntegerOperationDelegate addSquaresOfIntegersDelegate = (f, s) => (f * f) + (s * s);
IntegerOperationDelegate doSomethingRandomDelegate = (f, s) => (f + 3) * (s + 4);

We can then call DoAction as follows:

ProcessIntegers processIntegers = new ProcessIntegers();
processIntegers.DoAction(4, 5, addSquaresOfIntegersDelegate);
processIntegers.DoAction(4, 5, doSomethingRandomDelegate);

So it’s up to the caller to inject the correct rule on how to process the integers. The DoAction method will happily invoke the delegate without having prior knowledge on what’s going to happen to them.

These were a couple of simple examples on how custom delegates work with lambdas.

In the next sections we’ll see how to work with the delegates built into the .NET framework.

Action of T

Action of T represents a delegate that accepts a single parameter and returns no value. The Action object is of type ‘delegate’. You can pass in any object of type T. With Action of T you can skip declaring your delegate as ‘delegate void NameOfDelegate(params)’. Action of T provides a shorter solution to that as it already encapsulates a delegate. You can declare an Action as follows:

Action<string> actionOfString = MatchingActionOfT;
actionOfString("Test");

…where MatchingActionOfT is a method that takes a string to make sure it matches the delegate signature:

private static void MatchingActionOfT(string inputs)
{
	Console.WriteLine(inputs);
}

What if you need to pass in more parameters? That’s no problem as Action of T has 16 versions ranging from…

Action<in T>

…to

Action<in T1, in T2, ... , in T16>

If 16 separate input parameters are not enough then you need to seriously review your code.

You can even assign built-in methods to the Action if the method signature is correct:

Action<string> consoleString = Console.WriteLine;
consoleString("Test from console.");

Extend the ProcessIntegers class with the following method:

public void DoAction(int firstInteger, int secondInteger, Action<int, int> action)
{
        action(firstInteger, secondInteger);
	Console.WriteLine("Paramaters passed: {0}, {1}", firstInteger, secondInteger);
}

In Main we can declare our action:

Action<int, int> voidAction = (f, s) => Console.WriteLine(f + s);

…and then invoke it indirectly:

ProcessIntegers processIntegers = new ProcessIntegers();
processIntegers.DoAction(2, 2, voidAction);

The overloaded DoAction method will invoke the voidAction Action for us which will result in a printout on the console window.

Function of T, TResult

This is similar to Action of T. Its type is still ‘delegate’. The key difference is that it has a return value of type TResult. Just like with Actions you can pass in 16 parameters. The return type is always the last element in the type declaration. A function that takes two integers and returns a double will look like this:

Func<int, int, double> func = MatchingFuncOfT;

…and a matching method will take the following form:

private double MatchingFuncOfT(int first, int second)
{
	return first / second;
}

The Func delegate can be invoked as usual:

double res = func(3, 2);

In case the Func doesn’t accept any parameters then the single type declaration will be the return type:

Func<out T>

Just like with Action of T this method saves you the time and code declaring the custom delegate.

Previously in this post we added a custom delegate and created instances of that delegate using lambdas:

IntegerOperationDelegate addIntegersDelegate = (f, s) => f + s;
IntegerOperationDelegate addSquaresOfIntegersDelegate = (f, s) => (f * f) + (s * s);
IntegerOperationDelegate doSomethingRandomDelegate = (f, s) => (f + 3) * (s + 4);

We can achieve the same goal as follows:

Func<int, int, int> addIntegersFunction = (f, s) => f + s;
Func<int, int, int> addSquaresOfIntegersFunction = (f, s) => (f * f) + (s * s);
Func<int, int, int> doSomethingRandomFunction = (f, s) => (f + 3) * (s + 4);

Insert the following method into ProcessIntegers:

public void DoAction(int firstInteger, int secondInteger, Func<int, int, int> action)
{
	int res = action(firstInteger, secondInteger);
	Console.WriteLine("Func result: {0}", res);
}

We invoke the action in the usual way of invoking methods. We get the result and print it on the Console. Just like before, the DoAction method is not aware of what’s going on within the action.

We can call the overloaded DoAction method from Main as follows:

processIntegers.DoAction(2, 2, addIntegersFunction);
processIntegers.DoAction(4, 5, addSquaresOfIntegersFunction);
processIntegers.DoAction(4, 5, doSomethingRandomFunction);

Lambdas and Funcs in LINQ

Lambdas and Funcs are often used in LINQ when querying objects. Add a Product object to the solution:

public class Product
{
	public int Id { get; set; }
	public string Name { get; set; }
	public string Description { get; set; }
	public int OnStock { get; set; }
}

Add a ProductService with a list of all products and a method stub:

public class ProductService
{
	private List<Product> _allProducts = new List<Product>()
	{
		new Product(){Description = "FirstProduct", Id = 1, Name = "FP", OnStock = 456}
		, new Product(){Description = "SecondProduct", Id = 2, Name = "SP", OnStock = 123}
		, new Product(){Description = "ThirdProduct", Id = 3, Name = "TP", OnStock = 987}
		, new Product(){Description = "FourthProduct", Id = 4, Name = "FoP", OnStock = 432}
		, new Product(){Description = "FifthProduct", Id = 5, Name = "FiP", OnStock = 745}
		, new Product(){Description = "SixthProduct", Id = 6, Name = "SiP", OnStock = 456}
	};

	public void PlayWithLinq()
	{
	}
}

Start typing the following statement in PlayWithLinq:

IEnumerable<Product> filteredProducts = _allProducts.Where(

As you type ‘(‘ IntelliSense will show that Where accepts a Function of Product that returns a boolean. This means that the function will look at the Product objects in _allProducts and if there’s a match, i.e. the Func returns true, then the Product will be added to the List of products. Now that we know lambdas we can have something like this:

IEnumerable<Product> filteredProducts = _allProducts.Where(p => p.OnStock > 300);

‘p’ is the input parameter to the function, which will be a Product object from _allProducts. Then we have the lambda operator followed by the method body which returns a boolean. Just like above we can explicitly show the return statement if we want to:

IEnumerable<Product> filteredProducts = _allProducts.Where(p => { return p.OnStock > 300; });

You can call the input parameter as you wish: ‘p’, ‘prod’, ‘mickeymouse’ etc. The function takes a single parameter so we can omit the parenthesis, but you can also put ‘(p)’ if you want to. If the function accepts more parameters then we would need to add them within parenthesis. You can then simply iterate through the filtered products:

foreach (Product prod in filteredProducts)
{
	Console.WriteLine(prod.Id);
}

Call the method like this:

ProductService productService = new ProductService();
productService.PlayWithLinq();

…and you’ll see the filtered ids appear.

You can have multiple filtering criteria. As long as the method body returns a bool and accepts a Product it will be fine:

IEnumerable<Product> filteredProducts = _allProducts.Where(p => p.OnStock > 300 && p.Id < 4).OrderBy(p => p.Name);

We can extend our filter by an OrderBy clause which accepts a Function of T and returns a key of type TKey. The key is the property we want to order by:

IEnumerable<Product> filteredProducts = _allProducts.Where(p => p.OnStock > 300).OrderBy(p => p.Name);

Read the finishing post on this topic here.

Suspending a Task using SpinWait in .NET C#

You may want to put a Task to sleep for some time. You might want to check the state of an object before continuing. The Task continues after the sleep time.

One way to solve this is using the Thread.SpinWait method since the Task library uses .NET threading support in the background.

First construct your cancellation token:

CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;

Use this token in the constructor of the task:

Task task = Task.Factory.StartNew(() =>
{
	for (int i = 0; i < 100000; i++)
	{
		Thread.SpinWait(10000);
		Console.WriteLine(i);
		cancellationToken.ThrowIfCancellationRequested();
	}
}, cancellationToken);

You can use the cancellation token to interrupt the task:

cancellationTokenSource.Cancel();

We looked at Thread.Sleep and the WaitOne method in the previous posts on TPL. With those two techniques the thread that’s currently performing the task gives up its turn while sleeping. This gives a chance to other threads to do something. With spin waiting it’s different as the thread does not give up its turn.

The integer argument in SpinWait indicates an iteration. It is the number of times that a tight CPU loop will be performed. The exact amount of sleep time will depend on the speed of the CPU so it’s not some well defined period of time. Therefore spin waiting doesn’t stop using the CPU.

Bear in mind these limitations and use SpinWait with care – if ever.

View the list of posts on the Task Parallel Library here.

Cancel multiple Tasks at once in .NET C#

You cannot directly interrupt a Task in .NET while it’s running. You can do it indirectly through the CancellationTokenSource object. This object has a CancellationToken property which must be passed into the constructor of the Task:

CancellationTokenSource cancellationTokenSource	= new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;

You can re-use the same token in the constructor or several tasks:

Task firstTask = Task.Factory.StartNew(() =>
{
	for (int i = 0; i < 100000; i++)
	{
		cancellationToken.ThrowIfCancellationRequested();
		Console.WriteLine(i);
	}
}, cancellationToken);

Task secondTask = Task.Factory.StartNew(() =>
{
	for (int i = 0; i < int.MaxValue; i++)
	{
		cancellationToken.ThrowIfCancellationRequested();
		Console.WriteLine(i);
	}
}, cancellationToken);

We simply count up to 100000 in the Task bodies. We’re using the ThrowIfCancellationRequested() method of the cancellation token, I’ll explain shortly what it does.

You can cancel both tasks by calling the Cancel() method of the token like this:

cancellationTokenSource.Cancel();

Note that this method only signals the wish to cancel a task. .NET will not actively interrupt the task, you’ll have to monitor the status through the IsCancellationRequested property. It is your responsibility to stop the task. In this example we’ve used the built-in “convenience” method ThrowIfCancellationRequested() which throws an OperationCanceledException which is a must in order to correctly acknowledge the cancellation. If you forget this step then the task status will not be set correctly. Once the task has been requested the stop it cannot be restarted.

If you need to do something more substantial after cancellation, such as a resource cleanup, then you can monitor cancellation through the IsCancellationRequested and throw the OperationCanceledException yourself:

for (int i = 0; i < 100000; i++)
{
	if (token.IsCancellationRequested)
	{
		Console.WriteLine("Task cancellation requested");
		throw new OperationCanceledException(token);
	}
	else
	{
		Console.WriteLine(i);
	}
}

View the list of posts on the Task Parallel Library here.

Events, delegates and lambdas in .NET C# part 4: subscribing to events

Introduction

We saw in the previous post how to add delegates, events and event handlers to our SuperHero class. We also discussed that the standard signature for a delegate in .NET accepts the sender as an objects and another object that inherits from the EventArgs class. You may of course define your delegate as you like but consumers of your class will be expecting the standard signature.

The missing piece now is to wire up those elements. The key is to understand how to add an element to the invocation list. Then as the event fires the elements – methods – will be called one after the other in that list.

Demo

Open the project we’ve been working on in this series. The goal is to create a SuperHero object and subscribe to its events. You can imagine that Program.cs is the police chief who sends out a hero to save the world but wants him/her to report the progress and outcome of the work done.

In Main declare a new SuperHero:

SuperHero superman = new SuperHero();

There’s a number of ways you can subscribe to the events of the superhero. Start typing “superman.” in the editor and IntelliSense will list the available events denoted by a lightning bolt. You add elements to the invocation list with the “+=” operator. So type…

superman.WorldSaved +=

…in the editor and you’ll see that IntelliSense is trying to help you by automatically suggesting a method that will be created for you and which matches the delegate signature. Press TAB twice in order for this to happen. You should have the following method in Program.cs:

static void superman_WorldSaved(object sender, WorldSavedEventArgs e)
{
	throw new NotImplementedException();
}

This is called delegate inference. You didn’t have to new up a delegate yourself. The compiler will do it for you in the background.

Another way to get to the same result is to new up a WorldSavedHandler delegate and pass in the method that will be added to the invocation list:

superman.WorldSaved += new DelegatesIntro.WorldSavedHandler(superman_WorldSaved);

You can test to pass in a method that does not match the delegate signature: Visual Studio will complain immediately.

You can do it either way, it doesn’t make any difference to the outcome. The first option is probably more convenient as Visual Studio is guaranteed to create a method with the correct signature and you can save some code and time.

Modify the method to show some message on the console window:

static void superman_WorldSaved(object sender, WorldSavedEventArgs e)
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero reporting progress! Name: ")
		.Append(e.SaviourName).Append(", has been working for ").Append(e.WorkHasBeenOngoingHs)
		.Append(" hours, ").Append(" date of next occasion: ").Append(e.DateOfNextCatastrophy);
	Console.WriteLine(superHeroMessageBuilder.ToString());
}

The next step is to call on the superhero to finally start working:

superman.SaveTheWorld("Superman", DateTime.UtcNow.AddMonths(3));

Run the code and you’ll see that Superman reports the progress as expected. So you can see that this is kind of a nice way to get multiple values returned by a void method.

Let’s also subscribe to the other event of the superhero:

superman.WorldSavingCompleted += superman_WorldSavingCompleted;

…where superman_WorldSavingCompleted looks like this:

static void superman_WorldSavingCompleted(object sender, WorldSavingCompletedEventArgs e)
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero has saved the world! Name: ").Append(e.Saviour)
		.Append(", time spent saving the world: ").Append(e.HoursItTookToSaveWorld).Append(", message from the superhero: ")
		.Append(e.MessageFromSaviour);
	Console.WriteLine(superHeroMessageBuilder.ToString());
}

Run the code and you’ll see that the correct methods are called when the events fire.

If you want to remove a method from the invocation list then you can use the “-=” operator. If you insert the following – admittedly senseless – code, then you won’t see when the superhero has finished saving the world:

superman.WorldSavingCompleted += superman_WorldSavingCompleted;
superman.WorldSavingCompleted -= superman_WorldSavingCompleted;

Anonymous methods

So far we have declared the elements that react to events as standalone methods. There’s nothing wrong with that at all, but it’s not the only way. As an alternative you can embed the actions in something called an anonymous method which can only be used at the source of the subscription, i.e. where the “+=” operator is used. An anonymous method has no name and may look quite strange at first. You may have heard of “lambdas” before, but they are not the same thing as anonymous methods. They are similar features but still not quite the same. We’ll be looking into lambdas in a later post.

Anonymous methods are defined by the “delegate” keyword. It is followed by the input parameter declarations and finally the method body in curly braces. You close the whole statement with a semi-colon ‘;’.

So we can rewrite…

superman.WorldSavingCompleted += superman_WorldSavingCompleted;


static void superman_WorldSavingCompleted(object sender, WorldSavingCompletedEventArgs e)
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero has saved the world! Name: ").Append(e.Saviour)
		.Append(", time spent saving the world: ").Append(e.HoursItTookToSaveWorld).Append(", message from the superhero: ")
		.Append(e.MessageFromSaviour);
	Console.WriteLine(superHeroMessageBuilder.ToString());
}

…as follows:

superman.WorldSavingCompleted += delegate(object sender, WorldSavingCompletedEventArgs e)
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero has saved the world! Name: ").Append(e.Saviour)
		.Append(", time spent saving the world: ").Append(e.HoursItTookToSaveWorld).Append(", message from the superhero: ")
		.Append(e.MessageFromSaviour);
	Console.WriteLine(superHeroMessageBuilder.ToString());
};

We declare that whatever happens in case the event is fired, it is done right at the source. Note that this method can only be used “here and now” and not be called from anywhere else: it cannot be reused in other words. You may take this approach in case the method body is very simple and don’t want to write a dedicated method for it. In case the method body gets too long then you might want to break it out into a separate method.

We’ll start discussing lambdas, Func of T and Action of T in the next post.

Monitoring Task cancellation in .NET C# using a Wait handle

You cannot directly interrupt a Task in .NET while it’s running. You can do it indirectly through the CancellationTokenSource object. This object has a CancellationToken property which must be passed into the constructor of the Task:

CancellationTokenSource cancellationTokenSource	= new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;

The cancellation token can be used as follows:

// create the task
Task task = Task.Factory.StartNew(() =>
{
	for (int i = 0; i < 100000; i++)
	{
		if (cancellationToken.IsCancellationRequested)
		{
			Console.WriteLine("Task cancelled, must throw exception.");
			throw new OperationCanceledException(cancellationToken);
		}
		else
		{
			Console.WriteLine(i);
		}
	}
}, cancellationToken);

We simply count up to 100000 in the Task body. Note the IsCancellationRequested property of the token. We monitor within the loop whether the task has been cancelled.

The cancellation token has a property called WaitHandle which has a method called WaitOne(). This method blocks until the Cancel() method is called on the token source provided in the Task constructor. It can be used by setting up another Task which calls the WaitOne method which blocks until the first Task has been cancelled:

Task secondTask = Task.Factory.StartNew(() =>
	{
		cancellationToken.WaitHandle.WaitOne();
		Console.WriteLine("WaitOne called.");
	});

You can cancel the task by calling the Cancel() method of the token like this:

cancellationTokenSource.Cancel();

Note that this method only signals the wish to cancel a task. .NET will not actively interrupt the task, you’ll have to monitor the status through the IsCancellationRequested property. It is your responsibility to stop the task. In this example we throw an OperationCanceledException which is a must in order to correctly acknowledge the cancellation. If you forget this step then the task status will not be set correctly. Once the task has been requested the stop it cannot be restarted.

If that’s all you want to do, i.e. throw an OperationCanceledException, then there’s a shorter version:

cancellationToken.ThrowIfCancellationRequested();

This will perform the cancellation check and throw the exception in one step. The loop can thus be simplified as follows:

Task task = Task.Factory.StartNew(() =>
{
	for (int i = 0; i < 100000; i++)
	{
		//shorthand
        	cancellationToken.ThrowIfCancellationRequested();

		Console.WriteLine(i);
	}
}, cancellationToken);

View the list of posts on the Task Parallel Library here.

Events, delegates and lambdas in .NET C# part 3: delegates with events in action

Introduction

In the previous part of this series we looked at some examples of delegates. We also discussed the basics of events in .NET. We’re now ready to see some custom events in action.

Demo

Open the project we’ve been working on in this series. Add a new class to the project called SuperHero. Add the following method stub to SuperHero.cs:

public void SaveTheWorld(string saviourName, DateTime dateForNextCatastrophy)
{

}

Also, add the same delegate as we had before in Program.cs:

public delegate void WorldSavedHandler(string saviourName, DateTime dateForNextCatastrophy);

You can also put this is a separate class, it’s up to you.

Let’s say that an external class, such a police chief calls SuperHero to save the world and wants to monitor the progress. SaveTheWorld is void so we cannot read out anything from this method. However, we can raise events. We now know how to declare events so let’s add one to SuperHero.cs:

public event WorldSavedHandler WorldSaved;

The police chief will want to know when the world has been saved, i.e. the superhero’s work has completed. We can add an event handler for that. Add the following code just below the event declaration:

public event EventHandler WorldSavingCompleted;

EventHandler is the built-in .NET event handler that may look familiar to you from Windows UI programming. It is a delegate that does not return anything, accepts an object – the sender – and an EventArgs argument. So this is just a short-hand solution for a case where we don’t have any specialised event arguments. We only want to notify all listeners that the work has been completed. Note that EventHandler has a generic form as well: EventHandler of type T : EventArgs. Use this version if you want to specify a more specialised EventArgs class than the default empty EventArgs:

public event EventHandler<WorldSavingCompletedEventArgs> WorldSavingCompleted;

Then when you raise this event you’ll have to provide WorldSavingCompletedEventArgs to it instead of just EventArgs. Later on we’ll see an example of this.

We have now declared the events. The next step is to raise them. There are basically two ways to do that. One is to call an event like you would call a method:

if (WorldSaved != null)
{
	WorldSaved(saviourName, dateForNextCatastrophy);				
}

Another way is to extract the delegate from the event and invoke it:

WorldSavedHandler handler = WorldSaved as WorldSavedHandler;
if (handler != null)
{
	handler(saviourName, dateForNextCatastrophy);
}

Why do we check for a null value? It’s because if no other object has signed up with the event, i.e. there’s nothing in the invocation list, then the event will be null and you’ll get a null pointer exception if you try to raise it. It is the same as trying to call a method of an object that has not been initialised.

A common practice is to raise the event in a dedicated method and give that method a special name: ‘On’ + the name of the event, kind of like the familiar “OnClick” and “OnSelectedItemChanged” etc. methods. This is not a must for the event to work, only a possible way to organise your code:

public void SaveTheWorld(string saviourName, DateTime dateForNextCatastrophy)
{
	OnWorldSaved(saviourName, dateForNextCatastrophy);
}

private void OnWorldSaved(string saviourName, DateTime dateForNextCatastrophy)
{
	if (WorldSaved != null)
	{
		WorldSaved(saviourName, dateForNextCatastrophy);
	}
}

Let’s say that the police chief wants to monitor the superhero’s progress every hour. We’ll also hard code the duration of the superhero’s work to 4 hours to make this simple. So we’ll raise a WorldSaved event every hour to report some progress. At the end of the 4 hours we’ll raise a WorldSavingCompleted event to tell the world that the superhero has finished:

public void SaveTheWorld(string saviourName, DateTime dateForNextCatastrophy)
{
	int hoursToSaveTheWorld = 4;
	for (int i = 0; i < hoursToSaveTheWorld; i++)
	{
		OnWorldSaved(i + 1, saviourName, dateForNextCatastrophy);
		Thread.Sleep(1000);
	}
	OnWorldSavingCompleted();
}

private void OnWorldSaved(int hoursPassed, string saviourName, DateTime dateForNextCatastrophy)
{
	if (WorldSaved != null)
	{
		WorldSaved(string.Concat(saviourName, " has been working for ", hoursPassed, " hour(s)"), 
			dateForNextCatastrophy);
	}
}

private void OnWorldSavingCompleted()
{
	if (WorldSavingCompleted != null)
	{
		WorldSavingCompleted(this, EventArgs.Empty);
	}
}

So we report every hour worked by the superhero. In the OnWorldSavingCompleted method we raise the default .NET event which accepts the sender as an object and an EventArgs class. The sender of the event is ‘this’, i.e. the current SuperHero object. We don’t have any data to transmit to the listeners so we use the EventArgs.Empty convenience method. We’ll see later on how to send your data with your custom EventArgs object.

This is quite a nice way of getting sort of multiple return values out of void methods. Indeed, all listeners will be notified of the events raised by the superhero.

Custom event arguments

We’ve seen two ways to create delegates in this post: directly with the ‘delegate’ keyword and by using the built-in EventHandler class that is a wrapper around a delegate. Before we see how to subscribe to these events from the outside we need know how to pass custom event arguments.

The usual and standard way in .NET to create events is by specifying a method signature where the handling method will accept the sender as an object and an EventArgs. You must have seen that before if you did any Windows GUI development. We’ve also seen an example of that in OnWorldSavingCompleted(). However, that is kind of limiting as the default EventArgs is – almost – empty, you cannot supply your own messages to it.

Creating a custom EventArgs is very easy: create a class and inherit from the EventArgs object. You are then free to put an as many properties as you wish. You don’t need to worry about extending a parameter list of some delegate, you can just add new properties to your event args class. Add the following class to the project:

public class WorldSavingCompletedEventArgs : EventArgs
{
	public string Saviour { get; set; }
	public DateTime TimeForNextCatastrophy { get; set; }
	public int HoursItTookToSaveWorld { get; set; }
        public string MessageFromSaviour { get; set; }
}

The naming convention is to take the name of the event and attach ‘EventArgs’ to it. All the data that needs to be wired to the listeners is now encapsulated within this event args object. It is easy to extend and the properties are easily extracted from it.

Let’s clean up the WorldSavedHandler delegate. Add the following custom event args:

public class WorldSavedEventArgs : EventArgs
{
	public string SaviourName { get; set; }
	public DateTime DateOfNextCatastrophy { get; set; }
}

The WorldSavedHandler will take the following form:

public delegate void WorldSavedHandler(object sender, WorldSavedEventArgs e);

You’ll get compiler errors because we’ve changed the signature of the handler, we’ll correct it in a bit. As hinted at above the EventHandler object has a generic form to specify the type of the event handler. An advantage of using the EventHandler class will ensure that you’re sticking to the standard event signature. Modify the WorldSavingCompleted event handler to the following:

public event EventHandler<WorldSavingCompletedEventArgs> WorldSavingCompleted;

We can keep both examples, i.e. the delegate and the EventHandler in this demo project so that you can see both approaches, but in practice it’s more convenient to just stick to EventHandler and EventHandler of T. Using the EventHandler object saves having a separate delegate. Use the delegate-event-pair approach if you need access to the delegate on its own, i.e. without the matching event. Let’s clean up our code so that it compiles:

public delegate void WorldSavedHandler(object sender, WorldSavedEventArgs e);

public class SuperHero
{
	public event WorldSavedHandler WorldSaved;
	public event EventHandler<WorldSavingCompletedEventArgs> WorldSavingCompleted;

	public void SaveTheWorld(string saviourName, DateTime dateForNextCatastrophy)
	{
		int hoursToSaveTheWorld = 4;
		for (int i = 0; i < hoursToSaveTheWorld; i++)
		{
			OnWorldSaved(i + 1, saviourName, dateForNextCatastrophy);
			Thread.Sleep(1000);
		}
		OnWorldSavingCompleted(hoursToSaveTheWorld, "Yaaay!", saviourName, dateForNextCatastrophy);
	}

	private void OnWorldSaved(int hoursPassed, string saviourName, DateTime dateForNextCatastrophy)
	{
		if (WorldSaved != null)
		{
			WorldSavedEventArgs e = new WorldSavedEventArgs()
			{
				DateOfNextCatastrophy = dateForNextCatastrophy
				, SaviourName = saviourName
				, WorkHasBeenOngoingHs = hoursPassed
			};
			WorldSaved(this, e);
		}
	}

	private void OnWorldSavingCompleted(int totalHoursWorked, string message, string saviour, DateTime timeOfNextCatastrophy)
	{
		if (WorldSavingCompleted != null)
		{
			WorldSavingCompletedEventArgs e = new WorldSavingCompletedEventArgs()
			{
				HoursItTookToSaveWorld = totalHoursWorked
				, MessageFromSaviour = message
				, Saviour = saviour
				, TimeForNextCatastrophy = timeOfNextCatastrophy
			};
			WorldSavingCompleted(this, e);
		}
	}
}

You’ll see the revised delegate and event handler definitions. They follow the sender/eventargs convention. You also see how easy it is to wire data through the custom event args to the listeners.

Now the SuperHero class is ready to work and make announcements. But no-one is listening yet to catch those event notifications. We’ll see how to do just that in the next post.

Monitoring Task cancellation in .NET C# using a delegate

You cannot directly interrupt a Task in .NET while it’s running. You can do it indirectly through the CancellationTokenSource object. This object has a CancellationToken property which must be passed into the constructor of the Task:

CancellationTokenSource cancellationTokenSource	= new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;

The cancellation token can be used as follows:

// create the task
Task task = Task.Factory.StartNew(() =>
{
	for (int i = 0; i < 100000; i++)
	{
		if (cancellationToken.IsCancellationRequested)
		{
			Console.WriteLine("Task cancelled, must throw exception.");
			throw new OperationCanceledException(cancellationToken);
		}
		else
		{
			Console.WriteLine(i);
		}
	}
}, cancellationToken);

We simply count up to 100000 in the Task body. Note the IsCancellationRequested property of the token. We monitor within the loop whether the task has been cancelled.

You can register a delegate on the token that should be called when the task is cancelled:

cancellationToken.Register(() =>
{
	DoSomethingUponTaskCancellation();
});

You can clean up resources, cancel other tasks that rely on this particular task, notify the user, log the cancellation etc., it’s up to you how you implement the delegate. The Register method accepts an Action object or an Action of T which allows you to provide a state parameter.

You can cancel the task by calling the Cancel() method of the token like this:

cancellationTokenSource.Cancel();

Note that this method only signals the wish to cancel a task. .NET will not actively interrupt the task, you’ll have to monitor the status through the IsCancellationRequested property. It is your responsibility to stop the task. In this example we throw an OperationCanceledException which is a must in order to correctly acknowledge the cancellation. If you forget this step then the task status will not be set correctly. Once the task has been requested the stop it cannot be restarted.

If that’s all you want to do, i.e. throw an OperationCanceledException, then there’s a shorter version:

cancellationToken.ThrowIfCancellationRequested();

This will perform the cancellation check and throw the exception in one step. The loop can thus be simplified as follows:

Task task = Task.Factory.StartNew(() =>
{
	for (int i = 0; i < 100000; i++)
	{
		//shorthand
        	cancellationToken.ThrowIfCancellationRequested();

		Console.WriteLine(i);
	}
}, cancellationToken);

View the list of posts on the Task Parallel Library here.

Exception handling in the .NET Task Parallel Library with C#: a safety catch-all

In the previous posts on exception handling in Tasks (here, here, and here) we saw how to handle exceptions thrown by tasks. We saw that unhandled aggregate exceptions will be re-thrown by the default escalation policy. This will lead your application to be terminated immediately. If there are other ongoing tasks in that moment then those will be terminated too.

There can be situations that your application uses threads to such an extent that you either cannot put a try-catch block around every single Task.Wait, Task.WaitAll etc. calls or you simply forget it. There is a way to subscribe to all unhandled aggregate exceptions that the task scheduler encounters. You can then decide what to do with the exception there.

The task scheduler has an UnobservedTaskException event. It’s straightforward to subscribe to that even with the += operator.

TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

…where the event handler looks like this:

static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
	e.SetObserved();
	((AggregateException)e.Exception).Handle(ex =>
	{
		Console.WriteLine("Exception type: {0}", ex.GetType());
		return true;
	});
}

The SetObserved() method tells the task scheduler that the exception has been taken care of so there’s no need for it to bubble up. The UnobservedTaskExceptionEventArgs object has an Exception property that must be cast to an AggregateException. From then on you can call the Handle() method of the aggregate exception as we saw before.

Start a couple of new tasks:

Task.Factory.StartNew(() =>
{
	throw new ArgumentException();
});

Task.Factory.StartNew(() =>
{
	throw new NullReferenceException();
});

Wait a bit for the tasks to finish:

Thread.Sleep(100);

Run the code with Ctrl+F5 and… er… nothing happens really. The event handler is never triggered. You won’t see the aggregate exception type printed on the console window. What happened? The UnobservedTaskException handler will be called when the tasks with the unhandled exception have been collected by the garbage collector. As long as we are holding a reference to the two tasks the GC will not collect them, and we’ll never see the exception handler in action.

If we want to force the event handler to be fired then you can add the following two lines just below the Thread.Sleep bit:

GC.Collect();
GC.WaitForPendingFinalizers();

Run the code again and you’ll see the exception messages in the console window.

Note the following: in .NET4.5 there’s a new configuration element that specifies whether unhandled task exceptions should terminate the application or not:

<ThrowUnobservedTaskExceptions
   enabled="true|false"/>

True: terminate the process if an unhandled exception is encountered.
False (default): the exact opposite of the True case

In .NET4 the default behaviour is to terminate the process as we saw. In .NET4.5 it’s the exact opposite: unhandled exceptions still cause the UnobservedTaskException event to be raised, but the process will not be terminated by default. The exception will be silently ignored. So if you want to simulate .NET4 behaviour in a multi-threaded .NET4.5 application you’ll need to set the above mentioned configuration setting to true in the config file.

View the list of posts on the Task Parallel Library 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.