C# - Locking Example

5. November 2011 11:12

 

In this example we are going to use ThreadSimple to run a background which will happy process "something" until the input arrives. When input arrives in the console application we will aquire the lock which will block the background thread from running. The main idea here is to help give an visual understanding on what a lock between threads is actually doing in an application.

 

First off lets create a background thread. The only work it is performing is to print a counter to the screen and sleep for 100ms between runs. This uses the ThreadSimple class so you may need to read that post first.

 

 

class BackGround : ThreadSimple
{
	protected override void Run(object obj)
	{
		int Counter = 0;

		while (true)
		{
			lock (this)
			{
				Console.WriteLine("Running ... {0}", Counter);
				Counter++;
			}
			Thread.Sleep(100);
		}
	}
}

 

 

For the foreground thread which is where we are reciving end user input and we are using that to control the execution of the program. The idea here is to wait until return is pressed. Print something out then wait for 5 seconds until the lock is released and then the background thread continues to process what it was doing. Or in short it will present a message to an end user which would be visible for 5 seconds then continue what it was doing.

 

 

static void Main(string[] args)
{
	BackGround tmp = new BackGround();
	tmp.Start();


	Console.ReadLine();

	lock (tmp)
	{
		Console.WriteLine("Locking ...");
		Thread.Sleep(5000);
		Console.WriteLine("UnLocking");
	}

	Console.ReadLine();
	tmp.Stop();
}

 

 

When you run the application you should get the following output. With a 5 second delay after "Locking ...."

 

 

Running ... 0
Running ... 1
Running ... 2
Running ... 3
Running ... 4
Running ... 5
Running ... 6
Running ... 7
Running ... 8
Locking ...
UnLocking
Running ... 9
Running ... 10
Running ... 11
Running ... 12
Running ... 13
Running ... 14
Running ... 15
E-mail Kick it! DZone it! del.icio.us Permalink


C# - Number Of Cores and Processors

27. October 2011 13:55

 

If your working with threads in c# is can be useful to be able to find out the number of processors and the total number of cores avilable to an application so that you can adjust the maximum number of threads to a sensible value when an application starts. After all there is no point in attempting to execute 100 high processor intensive task's in a system with only 2 cores. It will just grind your application and possibly windows to a complete halt.

 

Heres is some code to find that information out

 

public static class ThreadSystemInfo
{
	private static bool HasData = false;

	private static void Init()
	{
		if (HasData)
			return;

		ObjectQuery wql = new ObjectQuery("SELECT * FROM Win32_Processor");
		ManagementObjectSearcher searcher = new ManagementObjectSearcher(wql);
		ManagementObjectCollection results = searcher.Get();

		foreach(ManagementObject result in results) {
			_NumberOfCores = int.Parse(result["NumberOfCores"].ToString());
			_NumberOfLogicalProcessors = int.Parse(result["NumberOfLogicalProcessors"].ToString());
			break;
		}

		HasData = true;
	}

	private static int _NumberOfCores = 0;
	public static int NumberOfCores
	{
		get
		{
			Init();
			return _NumberOfCores;
		}
	}

	private static int _NumberOfLogicalProcessors = 0;
	public static int NumberOfLogicalProcessors
	{
		get
		{
			Init();
			return _NumberOfLogicalProcessors;
		}
	}
}

E-mail Kick it! DZone it! del.icio.us Permalink


C# - ThreadPooled

22. October 2011 10:34

 

This is another example in a series of posts for working with thread in c#. In this example it shows how to create a custom thread pool. If you know anything about working with threads in c# you will know that it already has a thread pool. However the existing thread pool is typically in flexible when attempting to write more complex systems.

 

The existing has support for a single queue which is executed on a first in first out bases (fifo). This has a poor limit as it make it impossible to balance the load between tasks. An example would be backgrounding a lot of releatively unimportant taks then not being able to execute a high priority task as quickly as possible in the standard thread pool. It would also not permit the programmer to be able to balance task's. In that case of having a maximum number of threads (eg 5) for task X and a larger number of tasks (eg 20) for task Y.

 

Another approach to solving the above problem would be to use a priority queue. I will write about these in some later posts.

 

I did a previous example on how to create a basic thread queue. I would suggest that you read and understand it before trying to understand the following. Of course the basic queue will only execute one background task at a time. this example will execute many concurrent items at a time.

 

The basic variables we have in our class are almost the same as the basic queue. The only difference being that we needto clean up older threads when they are not being used. So I added a variable LastKilled to mark the time a spare thread exited because it didn't have any work. So we have the current variables.

 

 

private Queue<IRunnable> Q = new Queue<IRunnable>();
private DateTime LastKilled = DateTime.UtcNow;

 

Since we are a queue we need to be able to accept new items onto the thread. So we have almost the same Add method to add task's to our queue. The major difference being here is that if we do not have a spare thread or any active thread we will start a new thread so long as we are below our maximum number of permitted threads.

 

 

public void Add(IRunnable obj)
{
	lock (Q)
	{
		if (Q.Count > MaxItems)
			throw (new Exception("Too Many Items have been queued"));

		Q.Enqueue(obj);

		/* Mayby Start a new thread? */
		if (CurrentRunning >= CurrentThreads && CurrentThreads < MaxThreads)
		{
			ThreadSimpleRun tmp = new ThreadSimpleRun(this);
			tmp.Start();
			_CurrentThreads++;
		}

		Monitor.Pulse(Q);
	}
}

 

The part of code that changes significatly compared to the basic queue example is how item's are dequeued. Every time we start a new thread it will be executing on the following function. The Run function is used to take an item off the queue and execute it in the background. When there is no work to be done it will also sleep until a task is added to the queue and it is told to "wakeup" from the Add method above. At the same time the thread will sleep for a maximum time then "wakeup" if a significant period of time has passed with no work then it will exit to save on resources.

 

 

public void Run()
{
	while (true)
	{
		try
		{
			IRunnable item = null;

			lock (Q)
			{
				if (Q.Count == 0)
					Monitor.Wait(Q, ShrinkTime);

				if (Q.Count > 0)
				{
					item = Q.Dequeue();
					_CurrentRunning++;
				}
				else
				{
					if (LastKilled.AddMilliseconds(ShrinkTime) > DateTime.UtcNow)
					{
						_CurrentThreads--;
						return;
					}
				}
			}

			if (item == null)
				continue;	//Restart the loop

			item.Run();

			lock (Q)
			{
				_CurrentRunning--;
			}
		}
		catch (Exception ex)
		{
			throw (ex);
		}
	}
}

 

It is probably worth pointing out that we keep a count on the numbers of current executing threads and the total number of background threads. This is so the add function can decide when to create a new thread.

There is also an issue of error handling to be addressed. In this case we leave the error handling to be decided on in the "task". If an exception is passed back into the run function the exepected functionality is to crash. It is left in this way as only the queued tasks will know how to deal with their own error's.

I have left a small deliberate mistake in the code above. It will still function correctly but there is still a slight room for improvment. I wonder if anyone would be able to spot it?

 

Here is a copy of the complete class. Now you can create as many thread pools in c# as you require.

 

 

public class ThreadPooled : IRunnable
{
	private Queue<IRunnable> Q = new Queue<IRunnable>();
	private DateTime LastKilled = DateTime.UtcNow;

	public ThreadPooled()
	{

	}

	public void Add(IRunnable obj)
	{
		lock (Q)
		{
			if (Q.Count > MaxItems)
				throw (new Exception("Too Many Items have been queued"));

			Q.Enqueue(obj);

			/* Mayby Start a new thread? */
			if (CurrentRunning >= CurrentThreads && CurrentThreads < MaxThreads)
			{
				ThreadSimpleRun tmp = new ThreadSimpleRun(this);
				tmp.Start();
				_CurrentThreads++;
			}

			Monitor.Pulse(Q);
		}
	}

	public void Run()
	{
		while (true)
		{
			try
			{
				IRunnable item = null;

				lock (Q)
				{
					if (Q.Count == 0)
						Monitor.Wait(Q, ShrinkTime);

					if (Q.Count > 0)
					{
						item = Q.Dequeue();
						_CurrentRunning++;
					}
					else
					{
						if (LastKilled.AddMilliseconds(ShrinkTime) > DateTime.UtcNow)
						{
							_CurrentThreads--;
							return;
						}
					}
				}

				if (item == null)
					continue;	//Restart the loop

				item.Run();

				lock (Q)
				{
					_CurrentRunning--;
				}
			}
			catch (Exception ex)
			{
				throw (ex);
			}
		}
	}

	public int QueueLength
	{
		get
		{
			lock (Q)
			{
				return Q.Count;
			}
		}
	}

	private int _MaxItems = int.MaxValue;
	public int MaxItems
	{
		get
		{
			return _MaxItems;
		}
		set
		{
			lock (Q)
			{
				if (QueueLength > _MaxItems)
					throw (new Exception("Cannot shrink queue because it already contains more than MaxItems"));
				_MaxItems = value;
			}
		}
	}

	private int _MinThreads = 0;
	public int MinThreads
	{
		get
		{
			return _MinThreads;
		}
		set
		{
			_MinThreads = value;
		}
	}

	private int _CurrentRunning = 0;
	public int CurrentRunning
	{
		get
		{
			return _CurrentRunning;
		}
		set
		{
			_CurrentRunning = value;
		}
	}

	private int _CurrentThreads = 0;
	public int CurrentThreads
	{
		get
		{
			return _CurrentThreads;
		}
	}

	private int _MaxThreads = int.MaxValue;
	public int MaxThreads
	{
		get
		{
			return _MaxThreads;
		}
		set
		{
			_MaxThreads = value;
		}
	}

	private int _ShrinkTime = 60000;
	public int ShrinkTime
	{
		get
		{
			return _ShrinkTime;
		}
		set
		{
			_ShrinkTime = value;
		}
	}
}

 

E-mail Kick it! DZone it! del.icio.us Permalink


C# ThreadQueue example.

4. October 2011 19:32

 

This is an example on how to create a thread queue. It is part of a series of posts the full list is avilable here. You may need to look at the previous examples to understand what is happening in the other classes. In this example we will basic a basic class that can be reused to process a queue of items in a background thread.

 

The first thing I should probably point out is that the .net framework does not have an IRunnable interface like java does. I am not sure why this is or at least I have never found something like it. So we will need to create an IRunnable interface this is so that any sort of object passed to the class can be runnable by the queue processor. As any object passed will be required to be implement the same Run function. Code is below for the interface.

 

 

public interface IRunnable
{
	void Run();
}

 

 

Next we are going to create a class which is using the ThreadSimple so that it can run as a background task. We are also going to add a number of functions.

 

  • Add - To add an item to the queue
  • Run - To process the queue and execute the IRunnable interface function.
  • Error event. Fired if when an item throws and exception.
  • Complete event. First then an item finished executing.
  • Count property so the outside world can see how many items are queued.
  • Maximum length property so we can throw an error if too many items are added.

 

We will also add the correct locks to prevent the background thread and the normal application thread from trying to access and modifiy any object's at the same times. This typically caused an issues and headaches in multithreaded programming. The purpose of encapsulating these into the class from the outside world is to limit the scope of locks so that some of the more nasty dfficult bugs occur. If you don't have access to a variable you can't lock it!.

 

First lets keep it simple. We only need the functions Add and Run to demonstrate that this works. We will also start our background thread from the constructor for the queue which is in the ThreadSimple abstract class. It probably also worth pointing out that with lock's we only want to hold the lock for a short period of time. 

 

 

public class ThreadQueue : ThreadSimple
{
	private Queue<IRunnable> Q = new Queue<IRunnable>();

	public ThreadQueue()
	{
		Start();
	}

	public void Add(IRunnable obj)
	{
		lock (Q)
		{
			Q.Enqueue(obj);
		}
	}

	protected override void Run(object obj)
	{
		while (true)
		{
			try
			{
				IRunnable item = null;

				lock (Q)
				{
					if (Q.Count > 0)
						item = Q.Dequeue();
				}
				if (item == null)
				{
					Thread.Sleep(100);
					continue;	//Restart the loop
				}

				item.Run();
			}
			catch (Exception ex)
			{
				throw (ex);
			}
		}
	}
}

 

 

The above example is quite simple. Did you notice the problem though? The sleep should not exist. There is a better way for getting a background thread the sleep until something is added to the queue. We can do this using the class called Monitor. The idea behind this is to send a pulse to anything that is "sleeping" on the object to wake it up. The other thread will then wakeup and start processing the items.

The technical problem with this is normally getting to sleep. The idea is you lock the object then check the state. If the state is such that you need to sleep since there is no work todo then you sleep until somebody changed the state and notifies you. The Monitor.Wait is a special function that will allow you to sleep and unlock the object so that something else can aquire a lock. The lock is then reaquired when the thread wakes.

 

Our code will turn into something like this after the changes.

 

 

public void Add(IRunnable obj)
{
	lock (Q)
	{
		Q.Enqueue(obj);
		Monitor.Pulse(Q);
	}
}

protected override void Run(object obj)
{
	while (true)
	{
		try
		{
			IRunnable item = null;

			lock (Q)
			{
				if (Q.Count == 0)
					Monitor.Wait(Q);

				if (Q.Count > 0)
					item = Q.Dequeue();
			}
			if (item == null)
				continue;	//Restart the loop

			item.Run();
		}
		catch (Exception ex)
		{
			throw (ex);
		}
	}
}

 

I am going to leave the the exercise up the the end reader on implementing the other minor functions for queue length / maximum and events for error's and the when an item is completed. It is also possible to notify from the IRunnable object passed when it has finished executing.

 

What you may not have noticed is that there is an issue about how to destory the class. Since the thread in the background is still running. This really comes down to a design decision depending on your applications. It may be effective to never exist. However let's consider it is required. Another choice may be to stop adding things to the thread wait until the queue is empty then call the Stop function to kill the background thread.

Another possible option that I have used in the past is the make the ThreadQueue support the Dispose method and also inheirt the IDisposeable interface (the standard way todo it in .net). You could then have this function call the stop or an abort (see Thread.Abort) to kill the background thread. Raise an error event on all remaining items on the queue.

 

In the next post I will be focusing more on making this more generic and to support a forceful cancel method.

E-mail Kick it! DZone it! del.icio.us Permalink


C# - Improving the abstract thread class

3. October 2011 18:00

 

In the previous post I covered the threading code to an abstract class so that it could be reused to create background threads with minimum amount of code to be written. It's going to be improved in two ways, Add some error handling and also add a property so that somebody using the class can find out if the thread is actually running or not.

 

For the first part lets add some error handling. This needs to be done so that the ThreadSimple can catch a thread if it dies so that it can actually return a valid state if it is running or not. Todo this we are going to modify the thread start code and call an private function which will be used to trap any errors then call the abstract run class which will be implemented by the class that inherits ours.

 

We will end up with the following code.

 

 

public abstract class ThreadSimple
{
	protected Thread Thd = null;

	public void Start()
	{
		if (Thd != null)
			throw (new Exception("Thread Already Running"));
		Thd = new Thread(new ParameterizedThreadStart(DoRun));
		Thd.Start();
	}

	public void Stop()
	{
		if (Thd != null)
		{
			Thd.Abort();
			Thd = null;
		}
		else
		{
			throw (new Exception("Thread Already Stopped"));
		}
	}

	private void DoRun(object args)
	{
		Run(args);
	}

	protected abstract void Run(object obj);
}

 

We also need to add the error catch. Though if we catch an error we probably have to tell somebody about it. Or at least make it possible to tell the rest of the program outside our class. We can use an event handler for this. Actually we could probably do with several events being raised. eg on stop and on the error. I will only show how the error works here and you can implement as many events for states changes as you like!

 

Events normally need some class for EventArgs. So lets add the following to the project.

 

public class ThreadSimpleError : EventArgs
{
	public Exception ex = null;

	public ThreadSimpleError(Exception ex)
	{
		this.ex = ex;
	}
}

 

We also need to add the event and modify our DoRun function to catch the error and raise the event if an error occurs.

 

public event EventHandler<ThreadSimpleError> Error;

private void DoRun(object args)
{
	try
	{
		Run(args);
	}
	catch (Exception ex)
	{
		if (Error != null)
			Error(this, new ThreadSimpleError(ex));
	}
	Thd = null;
}

 

So now the application code can detect error's from us. If you are wondering how to get this to work with the windows forms then have a look at another previous post and pay particular attention to the Invoke section.

 

Another useful part of functionality we can also add would the ability for the code using the background thread to be able to find out if we are actually running or not. Since we know that the Thd variable is always going to be null when we are not running and a valid thread when we are we can use that to return our current running state. We should add this to our abstract class ThreadSimple.

 

 

public bool IsRunning
{
	get
	{
		if (Thd == null)
			return false;
		return true;
	}
}

 

So now we have an abstract class that we can use to create start / stop as many background processes as well like. Though we still are not doing anything useful yet. The next few posts coming are going to describe how to start to send information to the background process so that we can actually get things done in the background.

E-mail Kick it! DZone it! del.icio.us Permalink