C# - Background Thread / Task

29. September 2011 21:14

 

I did some previous posts on threads involving the thread pool and updating controls on a form from a background thread. In this example we are gonig to look at a little bit of a different approach. This will show you how to create a class to handle the background thread. The idea behind this sort of approach is to control the scope of what the different threads can see and operate on. This can help prevent deadlocks and other issues occuring when multiple threads. I am going to be writting multiple posts about this so I will be keeping them very simple to begin with.

 

The basic idea for this is to create a class which will control the start / stop and running state of the background thread. The reasons for this will become clear in the following posts. For this example I am using the class called ThdExample.

 

First we will need a few variables to work with.

 

private Thread Thd = null;
private int Value = 0;

 

 

We will have a public start function that can start to execute our thread. You can already see in this function that it will now be impossible for us to accidently start the same thread twice. This is part of the purpose of wrapping the thread into a single object which is not visible by the rest of the application.

 

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

 

 

Now we have some code to start a thread we will also need some code to be able to stop the thread from running. Again this code will throw an exception if you attempt to stop a thread that is already stopped.

 

 

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

 

Since we are running a background thread we do actually want to process something. I did mention I was going to keep this simple. So we are just going to print some incrementing values to the console. We are also going to wrap an exception handler into the code. So if something does happen we can exit cleanly and also update the state of our object. Since this is the function that the thread was started on if we return from it the thread will cease to exist.

 

 

private void Run(object args)
{

	try
	{
		while (true)
		{
			Value++;

			Console.WriteLine("Value: {0}", Value);

			Thread.Sleep(1000);
		}
	}
	catch (Exception ex)
	{

	}
	Thd = null;
}

 

 

So you have been following this correctly so far you should have a class where the code looks something like this.

 

public class ThdExample
{
	private Thread Thd = null;
	private int Value = 0;

	public ThdExample()
	{

	}

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

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

	private void Run(object args)
	{

		try
		{
			while (true)
			{
				Value++;

				Console.WriteLine("Value: {0}", Value);

				Thread.Sleep(1000);
			}
		}
		catch (Exception ex)
		{

		}
		Thd = null;
	}
}

 

Of course we need a way to test the background task we have written to prove that it is actually working. So lets create a simple program to create two instances of our class and start the background threads, sleep for about ten seconds and then stop the thread and exit the program.

 

 

class Program
{
	static void Main(string[] args)
	{
		ThdExample x1 = new ThdExample();
		ThdExample x2 = new ThdExample();

		x1.Start();
		x2.Start();

		Thread.Sleep(10000);

		x1.Stop();
		x2.Stop();

		Console.WriteLine("Done");
		Console.ReadLine();
	}
}

 

As you can see the code that deals with the threads is now very simple a clean to deal with. Even though our application doesn't really do anything useful here the purpose is to demostrate a basic strucutre to build a complex background task on top of. In the next post I will show you how to make this code reusable so that only the run function will need to be written.

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


Scams - Facebook Scam

27. September 2011 21:09

 

Looks like a new facebook scam seems to be doing the rounds. Pretty simple really. It attempts to capture your login details to get access to your account. It arrives by email and looks like the following. It does actually look pretty real though! You can almost always detect these by placing the mouse over the link and looking at the site that appears at the bottom.

 

 

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


MSSQL - Checking Uptime

24. September 2011 18:00

 

In MSSQL Server it is posisble to fine the date and time the server was started. This can be useful if you have an issue should sql server be crashing or some such and somebody has set the service to automatically restart if it crashed. This could go unnoticed by people except for mayby a random sql disconnect error messages from an application then they appear to work perfectly a minute later.

 

To get the sql startup time we can use the following.

 

SELECT sqlserver_start_time FROM sys.dm_os_sys_info

 

The above will give up the sql start date time. However for this we want the time in minutes.

 

SELECT DATEDIFF(MINUTE, sqlserver_start_time, GETDATE()) FROM sys.dm_os_sys_info

 

Using the above information we can now generate a simple script and send out an email alert when sql server restarts.

 

DECLARE @TimeFromStart int
SELECT @TimeFromStart=DATEDIFF(MINUTE, sqlserver_start_time, GETDATE()) FROM sys.dm_os_sys_info

IF (@TimeFromStart <= 60)
BEGIN
	EXEC msdb.dbo.sp_send_dbmail
		@recipients = 'example@example.com',
		@body = 'SQL Server Was Restarted!',
		@subject = 'Alert: SQL Server Restarted'
END

 

You can then add this to a job and set it to run hourly. At this point you will then get email alerts whenever your sql server is restarted.

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


Windows 7 - Turning off Thumb.db

24. September 2011 16:25

 

I previous wrote about the annoying issue with windows 7 and the thumb.db where it creates and error when you try to delete a folder after viewing the contents. Here is a quick guide to remove the issue. However it can slow down the initial view on a folder.

 

  1. First run gpedit.msc
  2. Then navigate to Local Computer Policy->User Configuration->Administrator Templates -> Windows Components->Windows Explorer
  3. Then double click the "Turn off caching of thumbnail pictures". Set the property to enabled.

 

 

You will then need to update the group policy using gpupdate /force and then reboot. Or if it is not urgent to turn off it will apply after the next reboot or two. Depending on when the group policy is updated.

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


C# - Lookup hostname

17. September 2011 10:56

 

A short guide on how to lookup a host name in c# and return an ip address. The first thing you will probably notice is that you may get more than one hostname because of how dns looks. If you are writing a program using them you should start by using the first one returned and if it does not work try the others on the list.

 

Sounds complex? Well its not really. The following code does the lookup. Where Hostname is a string.

 

IPAddress[] Addr = Dns.GetHostAddresses(HostName);

 

Just after making this call it is a good idea to check if the addr contains zero items. As it is valid for the call to return zero addresses but still success because the host name is valid with a different record type. eg an MX record for mail servers but does not have an A record. It may also throw an exception on failure.

 

You can then loop over the Addr attempting to connect to the correct service. I am assuming here that your connect method would throw an exception if it was unable to connect to the service correctly.

 

bool Connected = false;
Exception LastEx = null;
for (int i = 0; i < Addr.Length; i++)
{
	try
	{
		MyClass.Connect(Addr[0]);
		Connected = true;
		break;
	}
	catch (Exception ex)
	{
		LastEx = ex;
	}
}

if (Connected == false)
{
	ShowErrorToUser(LastEx);
	return;
}

 

You may also want to show all the exception messages recived in a list to make things easyier for the end user to understand. As you may get different error messages per host.

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