Calculation Model
There are a number of calculations and data transformations that need to take place in order to produce the correct Leakage Calculation.
In order to complete the Leakage Calculation as fast as possible we are going to separate the calculations and data transformations in to different processes and control these processes using a Windows Service.
In order for a Windows Service to handle separate processes we will be using the Multi Threading abilities of the .NET Framework.
[edit]Windows Service Installation
To install a Windows Service, you could create an installation program that encapsulates the executable for deployment, which I find time consuming and inefficient when testing an application. Or, you could install the service though the InstallUtil.exe process that comes with the .NET Framework.
I created a simple batch file, install.bat, to simplify installation (and therefore testing) of the service. The batch script is shown below; uninstallation is as simple as creating another batch file, uninstall.bat, with exactly the same script, only substituting the /i (for install) with /u (for uninstall).

[edit]WCF (Windows Communication Foundation
[edit]Introduction
We needed to be able to communicate with the Window Service running on the server, from anywhere on the network and the Internet if needed. So the best possible solution was to use [Microsofts WCF], as it is very flexible and configurable.
[edit]Service Contract
We need to implement a service contract, this provides an interface that we can use to be able to communication with the service.

[edit]Command
Provides a method to invoke a command to the service, mainly used for testing and debugging
Get a list of Calculation that are available to be processed
Start all the calculations
[edit]StartByName
Start a single calculation process by its name
Stop all calculations and abort their threads
Stop all calculations and abort their threads
Return if any calculations are still running
[edit]Activity
Display the activity of all the processes that have ever happened since the service started
This returns back a String Array, and in each string a comma delimited structure.
Name, Id, Date/Time, Status
[edit]ActivityById
Returns the activity for a given Id
This returns back a String Array, and in each string a comma delimited structure.
Name, Id, Date/Time, Status
[edit]ActivityCancel
Clears all the Activity information
[edit]Multi Threading
[edit]Starting
Before we start the thread we need to ensure that when the Windows Service is closed, that all the threads are stopped. To do this you must set the thread to a background process withIsBackground
When a thread terminates because of its parent process, it stops dead, and no finally blocks are executed.
The same situation arises when a user terminates an unresponsive application via the Windows Task Manager, or a process is killed programmatically via Process.Kill.
Therefore Restarting the Windows Service will cause the threads to stop in their tracks, which is perhaps what you are after if you restart or stop a service.
Abort will work on a thread in almost any state – running, blocked, suspended, or stopped. However if a suspended thread is aborted, a ThreadStateException is thrown – this time on the calling thread – and the abortion doesn’t kick off until the thread is subsequently resumed.

[edit]Configuration
[edit]App.Config
The application configuration file can be configured to handle the different calculations, we are using the standard .NET configuration settings, using a Section Group, within the Config Sections tag, of WaterNet, and implementing the leakage section handler, as seen below:

To configure the separate calculations you add each calculation in to the leakage tag, as seen below:

Here is a list of possible configuration options available for the calculation plugins
The name of the Calculation Required
[edit]assembly_name
The assembly name to be used, comprising of the method and the Assembly name, both including the full namespace. Required
[edit]numberOfThreads
sets the maximum number of threads available for this process to run at any one time default = 1
[edit]isBackground
Indicating whether or not a thread is a background thread. default = True
[edit]priority
Indicating the scheduling priority of a thread.
default = Normal
A thread can be assigned any one of the following priority values:
Highest
AboveNormal
Normal
BelowNormal
Lowest