Showing posts with label TPL. Show all posts
Showing posts with label TPL. Show all posts

Saturday, 7 December 2013

Using TPL to avoid callback hell

In this example, we fire off three service calls which individually have a continuation of converting the resultant DTO to a model object.

We then call a fourth service, to get the Spot which only fires once all the previous three service calls have completed and created their model object.

var tasks = new Task[]
{
services.GetAsTask<DTOs.MoneyMarketRate>()
.ContinueWith(t => MoneyMarketRate = Mapper.Map<DTOs.MoneyMarketRate, MoneyMarketRate>(t.Result)),

services.GetAsTask<DTOs.InvestmentBoundaries>()
.ContinueWith(t => InvestmentBoundaries = Mapper.Map<DTOs.InvestmentBoundaries, InvestmentBoundaries>(t.Result)),

services.GetAsTask<DTOs.TradingDate>()
.ContinueWith(t => TradingDate = Mapper.Map<DTOs.TradingDate, TradingDate>(t.Result)),
};

Task.Factory.ContinueWhenAll(
tasks,
ts => services.GetAsTask<DTOs.Spot>()
.ContinueWith(t => Spot = Mapper.Map<DTOs.Spot, Spot>(t.Result)));
You can take a look at my Silverlight source project here:  https://github.com/stevenh77/UsingTasksToAvoidCallbackHell
The problem with this code is that the exceptions are not properly handled.  For that we can leverage async and await:
try 
{
var tasks = new []
{
services.GetAsync<DTOs.MoneyMarketRate, MoneyMarketRate>(x => MoneyMarketRate = x),
services.GetAsync<DTOs.InvestmentBoundaries, InvestmentBoundaries>(x => InvestmentBoundaries = x),
services.GetAsync<DTOs.TradingDate, TradingDate>(x => TradingDate = x),
};

await TaskEx.WhenAll(tasks);
await services.GetAsync<DTOs.Spot, Spot>(x => Spot = x);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}

I also refactored the service executor to use async and await and move the setting to the property to an action that can be passed in.
public class ServiceExecutor
{
const string BaseAddress = "http://localhost:8080/Services/";

public async Task GetAsync<TDto, TModel>(Action<TModel> actionToSetPropertyValue)
{
var client = new WebClient();
var serviceName = typeof(TDto).Name + ".ashx";
var response = await client.DownloadStringTaskAsync(new Uri(BaseAddress + serviceName, UriKind.Absolute));
var dto = JsonConvert.DeserializeObject<TDto>(response);
actionToSetPropertyValue.Invoke(Mapper.Map<TDto, TModel>(dto));
}
}

Refactored source:  https://github.com/stevenh77/UsingTasksToAvoidCallbackHellWithAsyncAndWait/

Saturday, 29 September 2012

C# Synchronization

Here are four examples of synchronization, firing three pieces of work and blocking until any of the three complete:

  • Tasks
  • ManualResetEvents with a WaitHandle
  • ManualResetEvent
  • Monitor Wait and Pulse

image_thumb[3]

using System;
using System.Threading;
using System.Threading.Tasks;

namespace Synchronisation
{
internal class Program
{
private static void Main(string[] args)
{
new TaskWaitAnyExample().Execute();
new ManualResetEventWithWaitHandle().Execute();
new ManualResetEventExample().Execute();
new MonitorWaitAndPulse().Execute();
}
}

public abstract class Example
{
protected string name = "Example";

public abstract void Execute();

protected void MethodA()
{
Console.WriteLine("{0}: Entering MethodA", name);
Thread.Sleep(20000);
Console.WriteLine("{0}: Exiting MethodA", name);
}

protected void MethodB()
{
Console.WriteLine("{0}: Entering MethodB", name);
Thread.Sleep(10000);
Console.WriteLine("{0}: Exiting MethodB", name);
}

protected void MethodC()
{
Console.WriteLine("{0}: Entering MethodC", name);
Thread.Sleep(1000);
Console.WriteLine("{0}: Exiting MethodC", name);
}
}

public class TaskWaitAnyExample : Example
{
public override void Execute()
{
name = "TaskWaitAnyExample";
Console.WriteLine("{0} (from .NET 4.0):", name);

var taskA = Task.Factory.StartNew(MethodA);
var taskB = Task.Factory.StartNew(MethodB);
var taskC = Task.Factory.StartNew(MethodC);

Console.WriteLine("Waiting for one task to finish");
Task.WaitAny(taskA, taskB, taskC);
Console.WriteLine("Signal received, time to move on{0}", Environment.NewLine);
}
}

public class ManualResetEventWithWaitHandle : Example
{
public override void Execute()
{
name = "ManualResetEventWithWaitHandle";
Console.WriteLine("{0} (from .NET 1.1):", name);

WaitHandle[] waitHandles = new WaitHandle[]
{
new ManualResetEvent(false),
new ManualResetEvent(false),
new ManualResetEvent(false)
};

ThreadPool.QueueUserWorkItem(o => { MethodA(); ((ManualResetEvent)waitHandles[0]).Set(); });
ThreadPool.QueueUserWorkItem(o => { MethodB(); ((ManualResetEvent)waitHandles[1]).Set(); });
ThreadPool.QueueUserWorkItem(o => { MethodC(); ((ManualResetEvent)waitHandles[2]).Set(); });

Console.WriteLine("Waiting for one signal that one work item has finished");
WaitHandle.WaitAny(waitHandles);
Console.WriteLine("Signal received, time to move on{0}", Environment.NewLine);
}
}

public class ManualResetEventExample : Example
{
private readonly ManualResetEvent manualResetEvent = new ManualResetEvent(false);

public override void Execute()
{
name = "ManualResetEvent";
Console.WriteLine("{0} (from .NET 1.1):", name);

ThreadPool.QueueUserWorkItem(o => { MethodA(); manualResetEvent.Set(); });
ThreadPool.QueueUserWorkItem(o => { MethodB(); manualResetEvent.Set(); });
ThreadPool.QueueUserWorkItem(o => { MethodC(); manualResetEvent.Set(); });

Console.WriteLine("Waiting for one signal that one work item has finished");
manualResetEvent.WaitOne();
Console.WriteLine("Signal received, time to move on{0}", Environment.NewLine);
}
}

public class MonitorWaitAndPulse : Example
{
readonly object locker = new object();
bool signalSent;

public override void Execute()
{
name = "Monitor Wait and Pulse";
Console.WriteLine("{0} (from .NET 1.1):", name);

ThreadPool.QueueUserWorkItem(o => DoWork(MethodA));
ThreadPool.QueueUserWorkItem(o => DoWork(MethodB));
ThreadPool.QueueUserWorkItem(o => DoWork(MethodC));

Console.WriteLine("Waiting for one signal that one work item has finished");

lock (locker)
while (!signalSent)
Monitor.Wait(locker);

Console.WriteLine("Signal received, time to move on{0}", Environment.NewLine);
}

private void DoWork(Action action)
{
action.Invoke();

lock (locker)
{
signalSent = true;
Monitor.Pulse(locker);
}
}
}
}

Saturday, 18 February 2012

TryExecute with timeout and maxAttempts

A nice piece of code for calling services with a timeout and maximum attempts, in case the service should cause an exception.

It follows the standard practise for "Try" in .Net, like TryParse, of returning a boolean to indicate success and the result as an out parameter. Should you wish to find out the exception that may have occurred this is also passed as an out parameter.

I've also included an Execute mthod that will raise an exception should the service request timeout or fail more than the maximum number of attempts,

The source code solution includes unit tests in MBUnit, NUnit, xUnit and MSTest:

http://stevenhollidge.com/blog-source-code/TryExecute.zip

Friday, 28 October 2011

TPL DataFlow C#

The new DataFlow library can build up pipelines for our data to flow through.

Perhaps you have a series of processes a file must go through in a defined sequence:

  1. Encrypt
  2. Compress
  3. FTP
  4. Archive

DataFlow allows for easy manipulation of concurrency, asynchronicity and build up of our data flow pipelines.

In this simple example a number is posted into the pipeline, to be transformed by doubling it.  It can then be passed to the ActionBlock for output to screen.

You can download the TPL DataFlow CTP from Microsoft:
http://msdn.microsoft.com/en-us/devlabs/gg585582

Monday, 23 May 2011

Common Tasks using the TPL

Want a quick way to remember how to spin up tasks in .Net 4.0?  Here’s a few examples:

Thursday, 19 May 2011

Multi threaded apps with Tasks

Here is an example of running multiple methods simultaneously:

ScreenShot026

The Task Parallel Library will decide whether new threads are required, and spin them up from the thread pool as required.

Chain of Command pattern with Tasks

You can create a new thread and that can run a series of sequential methods, with the result of each passed onto it’s successor using Tasks and the ContinueWith keyword. 

The example below uses a fluent interface to chain each method together:

image