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


Comments (2) -

3/8/2012 8:41:03 PM #

You shouldn´t use Thread.Abort() to kill a thread, you should use a flag instead to politely ask the thread to stop itself, that flag should be protected by a lock (or any other syncronization technique), or instead should be marked as volatile (if bool) so the compiler don´t apply any optimization and can be used between threads safely (read/write operations with bools are atomic guaranteed by the CLI, but if are not marked as volatile they don´t work because they can be put in cache).

Hell a BackGroundWorker make all of this for free!

yo Mexico |

3/8/2012 8:51:20 PM #


Actually that not always true. There is nothing wrong with Thread.Abort. It will however throw an exception that can be handled in the thread to undo anything.

The problem being here is that is an abstraction of it. The Stop will do what is asked. It will stop the thread...

But yes the thread could / should have a separate way to exit but it depends exactly what it is doing. There may be no way to wake it up.

james United Kingdom |

Pingbacks and trackbacks (1)+