Monday, June 29, 2009

Factory Pattern with Attributes. Get rid of the ugly switch / case.

2 comments:
Source Code: http://www.box.net/shared/2yh2r6l91c

A very common design pattern used in Object Oriented Programming, is the Factory Pattern. The purpose of this post isn't to explain the factory pattern or why it's useful, rather I want to show a simple way to eliminate a giant switch / case found in many factory pattern implementations. For some good reading on the Factory Pattern, I suggest reading these two articles:

Wikipedia : http://en.wikipedia.org/wiki/Factory_method_pattern

MSDN : http://msdn.microsoft.com/en-us/library/ms954600.aspx

To demonstrate a simple example of the Factory Pattern, I've created a few classes. First, I created a base Vehicle class that looks something like this:



public abstract class Vehicle
{
public virtual int TopSpeed
{
get
{
return 150;
}
}

public abstract int Wheels
{
get;
}

public override string ToString()
{
return String.Format("A {0} has {1} wheels, and a top speed of {2} MPH."
, this.GetType().Name, this.Wheels, this.TopSpeed);
}
}


Just a base class that has one virtual property, one abstract property, and it overrides ToString. Then, I've created 4 subclasses:



public class Car : Vehicle
{
public override int Wheels
{
get { return 4; }
}
}

public class SuperCar : Car
{
public override int TopSpeed
{
get
{
return 200;
}
}
}

public class Truck : Vehicle
{
public override int Wheels
{
get { return 18; }
}
}
public class Motorcycle : Vehicle
{
public override int Wheels
{
get { return 2; }
}

public override int TopSpeed
{
get
{
return 190;
}
}
}


So we have Vehicle, Car, SuperCar, Truck and Motorcycle. Now, say we wanted to create a Factory that returns us the correct Vehicle class based on an enum that we'd supply. So let's create an enum:



public enum VehicleType
{
Car,
SuperCar,
Truck,
Motorcyle
}


We'd then have a method that looks something like this:



public static Vehicle GetVehicle(VehicleType vehicle)
{
switch (vehicle)
{
case VehicleType.Car:
return new Car();
case VehicleType.SuperCar:
return new SuperCar();
case VehicleType.Truck:
return new Truck();
case VehicleType.Motorcyle:
return new Motorcycle();
default:
return null;
}
}

Well, this is all nice, and works fine, but imagine a scenario where you may have many many subclasses. This switch statement would get huge, and unmaintainable quickly. Imagine then that new subclasses come along, you'd have to first update the enum, and then remember to update this switch / case. Well, I think there's a better way to do this.

The premise is simple; create an attribute that has one property called Type. This attribute will go on the enum, and will represent which type should be instantiated for each value of the enum. So, let's first create the Attribute class:



public class VehicleInfoAttribute : Attribute
{
private Type type;

public VehicleInfoAttribute(Type type)
{
this.type = type;
}

public Type Type
{
get
{
return this.type;
}
}
}


Nothing fancy, just a simple attribute that will house the Type to be created. Now, let's go back to our enum, and decorate the values with the correct attributes:



public enum VehicleType
{
[VehicleInfo(typeof(Car))]
Car,

[VehicleInfo(typeof(SuperCar))]
SuperCar,

[VehicleInfo(typeof(Truck))]
Truck,

[VehicleInfo(typeof(Motorcycle))]
Motorcyle
}


Now, each enum has an attribute that tells us which type to be instantiated for that type. Now, the fun part. The reflection bit in the factory method itself:

First, I've created an extension method for enum's that helps with getting custom attributes off of enum values:



public static class Extensions
{
public static T GetAttribute<T>(this Enum enumValue)
where T : Attribute
{
FieldInfo field = enumValue.GetType().GetField(enumValue.ToString());
object[] attribs = field.GetCustomAttributes(typeof(T), false);
T result = default(T);

if (attribs.Length > 0)
{
result = attribs[0] as T;
}

return result;
}
}


This allows you to do something like this:

MyCustomAttribute a = myEnumValue.GetAttribute<MyCustomAttribute>();

Now, we have all the pieces in place to write the Factory Method:



public static Vehicle GetVehicle(VehicleType vehicle)
{
var vehicleAttribute = vehicle.GetAttribute<VehicleInfoAttribute>();
if (vehicleAttribute == null)
{
return null;
}

var type = vehicleAttribute.Type;
Vehicle result = Activator.CreateInstance(type) as Vehicle;

return result;
}


First we call our extension method to get the attribute value for the enum passed in. Then, we use the handy Activator.CreateInstance() to create an object of that type.

To test it out, we can write a quick app:



static void Main()
{
Vehicle v = VehicleFactory.GetVehicle(VehicleType.Truck);
Console.WriteLine(v);
}


This will output:

A Truck has 18 wheels, and a top speed of 150 MPH.

Using this approach, yields two benefits. First, you no longer have a giant ugly switch / case. Secondly, if you ever have a case where another subclass is added, you just add another enum value (which you'd have to do anyway if you were using the switch / case), slap on the attribute, and you're done. The Factory method doesn't need to change at all.

Tuesday, June 23, 2009

LINQ Overkill. Why? Ha! Why not??

No comments:
Source Code: http://www.box.net/shared/tnt1569ql9

Before going to SetFocus, we had to take a few test before being accepted. One of these tests was a simple coding exercise, which went something like this:

Write a program that accepts a string input from the user. Your program will then count the occurrence of each character in the string, and output the results in this format:

There are 0 A's.
There are 2 B's.
There are 1 C's.
...
...


Simple program really, with a few easy approaches. I personally used a HashTable to hold the chars and the integers. After going through SetFocus, and learning about generics, I rewrote the app to use a Dictionary<char,int>, and the app basically looked something like this:



private static void CountCharacters(string text)
{
Dictionary<char,int> chars = new Dictionary<char, int>();
for (int i = 65; i <= 90; i++) //character integer values for 'A' - 'Z'
{
chars.Add((char)i, 0);
}

foreach (var character in text.ToUpperInvariant())
{
if (chars.ContainsKey(character))
{
chars[character]++;
}
}

foreach (var kvp in chars)
{
Console.WriteLine("There are {0} {1}'s.", kvp.Value, kvp.Key);
}
}


Basically, populate the dictionary with the alphabet in upper case, initialize all int's to zero's. Then, loop through the text, and increment the corresponding integer. Finally, loop through the dictionary, and output the results.

Very nice. Recently however, I was bored one bight, and it hit me. Having used LINQ extensivley for quite a while now, I figured, I'm sure I can figure out a way to do this in a "LINQ one liner", ie. one gigantic impossible-to-understand LINQ statement. Why? Why not!!

So, here's what I came up with. I'm warning you, it's isn't pretty but it works. I'll try my best to explain after:



public static StringBuilder CountCharsAlexLinqMethod(string text)
{
var result = new StringBuilder();
foreach (var item in (from p in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
join pa in
(from p in text.ToUpperInvariant()
group p by p into g
select new { Count = g.Count(), Character = g.Key })
on p equals pa.Character into w
from a in w.DefaultIfEmpty()
select new
{
Count = a == null ? 0 : a.Count,
Character = p
}))
{
result.AppendFormat(Format, item.Count, item.Character);
}

return result;
}


Told you it wasn't pretty :) Ok, it looks worse than it is. The basic premise is as follows. First, let's analyze the inner query:


(from p in text.ToUpperInvariant()
group p by p into g
select new { Count = g.Count(), Character = g.Key })


Think of this as a "GROUP BY" in SQL. It basically groups all the letters together in the given text, and counts them up. So at this point, if our text for example was the word "Hello", then this collection of anonymous objects would look something like this:

{Character = 'H', Count = 1}
{Character = 'E', Count = 1}
{Character = 'L', Count = 2}
{Character = 'O', Count = 1}

Once we have that, we basically do the equivalent of a LEFT OUTER JOIN on the entire alphabet. Since string implements IEnumerable<char> we can query it just like any other IEnumerable and even join on it. So what's happening is, we're joining our results from the inner query earlier, to a collection that contains the entire alphabet. Wherever they join, meaning wherever the letter is found in the inner query, use that as the count, if not, use 0 as the count:


on p equals pa.Character into w
from a in w.DefaultIfEmpty()
select new
{
Count = a == null ? 0 : a.Count,
Character = p
}))


Crazy, but not too bad. Well, the story isn't over. Since I thought this was kinda neat, and I HAD to show someone, I decided to bug James Arendt who was one of my instructors at Set Focus and I sent him my code. Here was his response:

Fun solution, Alex! I don't use the group join too often so it was neat to see it in action on this solution. I decided to take a stab at the code as well, but I took a different direction.




private static void CountCharacters(string text)
{
// I could have used a literal, but I wanted to demonstrate some
// other LINQ routines.
var letters = Enumerable.Range('A', 26).Select(i => (char)i);
var sourceChars = letters.Concat(text.ToUpperInvariant());

var results = from c in sourceChars
group c by c into g
where char.IsLetter(g.Key)
orderby g.Key
select new { Char = g.Key, Count = g.Count() - 1 };

foreach (var result in results)
{
Console.WriteLine("There are {0} {1}'s.", result.Count, result.Char);
}
}


His approach is a little different. First, he builds up an enumerable with the alphabet without using literals (no real difference there). Then however, he tacks on the text to the end of that enumerable. So at this point, if our test text was "Hello", the enumerable would be:

'A','B','C','D'.....'Z','H','E','L','L','O'.

Then, he does a group by on this enumerable, counting up the duplicates.

Nice. So, whenever you have more than one way of doing something, what does every computer nerd like me love to do? Why benchmark of course!!

In my initial comparisons between my method and the way James did it, his way was quicker every time. I wrote back to him, and congratulated him that his way was in fact quicker, but he pointed out to me, that his way was only quicker with shorter strings. When the strings got really long, my way turned out to be fast. So, I decided to flesh this all out, and really benchmark all ways of doing it.

Before I do that, just for the sake of really doing it in just one line, I wrote it one more way:



public static StringBuilder CountCharsAlexLinqCompleteOverkill(string text)
{
var result = new StringBuilder();

(from p in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
join pa in
(from p in text.ToUpperInvariant()
group p by p into g
select new { Count = g.Count(), Character = g.Key })
on p equals pa.Character into w
from a in w.DefaultIfEmpty()
select new
{
Count = a == null ? 0 : a.Count,
Character = p
}).ForEach(item => result.AppendFormat(Format, item.Count, item.Character));

return result;
}

private static void ForEach<T>(this IEnumerable<T> list, Action<T> action)
{
foreach (var item in list)
{
action(item);
}
}


Not really THAT much different, but now it really is just one statement. There's a ForEach extension method now, so the actual CountCharacters method is just one big statement. So, here's the entire class I used for benchmarking:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LinqOverkill
{
public static class CharacterCounter
{
private const string Format = "There are {0} {1}'s.\n";

public static StringBuilder CountCharsDictionaryMethod(string text)
{
var chars = new Dictionary<char, int>();
for (int i = 65; i <= 90; i++) //character integer values for 'A' - 'Z'
{
chars.Add((char)i, 0);
}

foreach (var character in text.ToUpperInvariant())
{
if (chars.ContainsKey(character))
{
chars[character]++;
}
}

var result = new StringBuilder();


foreach (var kvp in chars)
{
result.AppendFormat(Format, kvp.Value, kvp.Key);
}

return result;
}

public static StringBuilder CountCharsAlexLinqMethod(string text)
{
var result = new StringBuilder();
foreach (var item in (from p in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
join pa in
(from p in text.ToUpperInvariant()
group p by p into g
select new { Count = g.Count(), Character = g.Key })
on p equals pa.Character into w
from a in w.DefaultIfEmpty()
select new
{
Count = a == null ? 0 : a.Count,
Character = p
}))
{
result.AppendFormat(Format, item.Count, item.Character);
}

return result;
}


public static StringBuilder CountCharsJamesLinqMethod(string text)
{
var builder = new StringBuilder();

var letters = Enumerable.Range('A', 26).Select(i => (char)i);
var sourceChars = letters.Concat(text.ToUpperInvariant());

var results = from c in sourceChars
group c by c into g
where char.IsLetter(g.Key)
orderby g.Key
select new { Char = g.Key, Count = g.Count() - 1 };

foreach (var result in results)
{
builder.AppendFormat(Format, result.Count, result.Char);
}

return builder;
}

public static StringBuilder CountCharsAlexLinqCompleteOverkill(string text)
{
var result = new StringBuilder();

(from p in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
join pa in
(from p in text.ToUpperInvariant()
group p by p into g
select new { Count = g.Count(), Character = g.Key })
on p equals pa.Character into w
from a in w.DefaultIfEmpty()
select new
{
Count = a == null ? 0 : a.Count,
Character = p
}).ForEach(item => result.AppendFormat(Format, item.Count, item.Character));

return result;
}

private static void ForEach<T>(this IEnumerable<T> list, Action<T> action)
{
foreach (var item in list)
{
action(item);
}
}
}
}


I then wrote a test method which tested it first with a short string of 24 characters, and then 4135 characters. Here's the main method:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace LinqOverkill
{
class Program
{
static void Main(string[] args)
{
string text = "This is some dummy text.";
int iterations = 10000;

BenchmarhMethods(text, iterations);

string bigText = LinqOverkill.Resource.BigText;
BenchmarhMethods(bigText, iterations);

Console.ReadKey(true);
}

private static void BenchmarhMethods(string text, int iterations)
{
Console.WriteLine("Testing with {0} characters.", text.Length);
Stopwatch watch = new Stopwatch();

watch.Start();
for (int i = 1; i <= iterations; i++)
{
CharacterCounter.CountCharsDictionaryMethod(text);
}
watch.Stop();
Console.WriteLine("Dictionary method took: {0} milliseconds.", watch.ElapsedMilliseconds);

watch.Reset();

watch.Start();
for (int i = 1; i <= iterations; i++)
{
CharacterCounter.CountCharsAlexLinqMethod(text);
}
watch.Stop();
Console.WriteLine("Alex LINQ method took: {0} milliseconds.", watch.ElapsedMilliseconds);

watch.Reset();

watch.Start();
for (int i = 1; i <= iterations; i++)
{
CharacterCounter.CountCharsAlexLinqCompleteOverkill(text);
}
watch.Stop();
Console.WriteLine("Alex Overkill method took: {0} milliseconds.", watch.ElapsedMilliseconds);

watch.Reset();

watch.Start();
for (int i = 1; i <= iterations; i++)
{
CharacterCounter.CountCharsJamesLinqMethod(text);
}
watch.Stop();
Console.WriteLine("James LINQ method took: {0} milliseconds.", watch.ElapsedMilliseconds);

watch.Reset();
Console.WriteLine();
}
}
}


Here were the results on my machine:

Testing with 24 characters.
Dictionary method took: 427 milliseconds.
Alex LINQ method took: 1176 milliseconds.
Alex Overkill method took: 1157 milliseconds.
James LINQ method took: 636 milliseconds.

Testing with 4135 characters.
Dictionary method took: 7484 milliseconds.
Alex LINQ method took: 6417 milliseconds.
Alex Overkill method took: 6429 milliseconds.
James LINQ method took: 6738 milliseconds.

As you can see, with 24 characters, using a Dictionary and looping yourself is the quickest way. Second quickest is the way James did it. Then, my way (the Alex LINQ and the overkill are basically the same exact thing) came in last.

When I pumped it up to 4135 characters though, my was fast fastest :) Even faster than using a Dictionary.

One final note. In production code, this really isn't a good idea. Yes, it's loads of fun to do, (I love doin stuff like this) but if another developer, or even you really, ever needs to go back to look at this code, it'll take them 3 times as long to figure out what's going on and how it's doing it.

Finally, I'll leave you with this example of the worst abuse of LINQ ever. It's awesome, but I have no clue what the heck it's doing!! http://blogs.msdn.com/lukeh/archive/2007/10/01/taking-linq-to-objects-to-extremes-a-fully-linqified-raytracer.aspx

Friday, June 19, 2009

C# Html Screen Scraping Part 2 / Performing POST with Cookies

1 comment:
Source code: http://www.box.net/shared/r7u052y507

I just want to point out, that I purposely didn't break this out into separate classes and methods, and I know I'm duplicating ALOT of code. I simply wanted to demonstrate each technique on its own.


In my previous post, I demonstrated how to connect to a website, and download the HTML (aka Screen Scraping). That all works nicely if it's a simple site you need to connect to. Sometimes however, you can't simply connect to the site and download the HTML, rather you need to first login, or maybe you need to enter some kind of search term first into a text box. In the HTML world, generally the page will have a simple form that posts to the server which queries the database or something based on the info supplied in the post, and then dynamically builds up the page. How do you do that in your C# app? How do you pass the values on to the Form Post that the server is expecting?

Throughout this post, I'll be referring to the code that's attached to this post. It basically has two projects. One's a simple ASP.NET MVC website, and the other is a winforms app. In order to run this properly, you'll need to first launch the web app, and then launch the windows app. Here's a simple screen shot of what the windows app looks like so you can get an idea:



First, a little note. In order to demonstrate this, I needed a site that had a simple Form with cookies. Since I couldn't find anything that was really simple and that would be easy to demo, I decided to create my own little "Website". It's written in ASP.NET MVC, so if you want to be able to run the code sample supplied in the link, head over to the ASP.NET MVC Website and download it (if you don't already have it.)

The site basically has two URL's that are of interest. The first is ../Home/SimplePost. If you navigate to that page, you'll see a simple textbox with a button. When you click the button, it simply posts the text in the textbox back to the server, and then it just outputs it back to the browser. Here's the HTML rendered for that form:

<form action="/Home/SimplePost" method="post">
<input type="text" id="text" name="text" />
<input type="submit" value="submit" />
</form>

The Form will Post to a site on the server /Home/SimplePost. We also can see in the form, that the server is expecting a parameter that's called "text". It's safe to assume, that anything with an input field (except for the button) is needed by the server. So, now we have enough info to write our C# function:



private void PostWithoutCookies()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
String.Format("http://localhost:{0}/Home/SimplePost", port));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string postData = String.Format("text={0}", String.IsNullOrEmpty(textBoxPost.Text)
? "somerandomemail@address.com" : this.textBoxPost.Text);
byte[] bytes = Encoding.UTF8.GetBytes(postData);
request.ContentLength = bytes.Length;

Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);

WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
stream.Dispose();
reader.Dispose();
this.richTextBox1.Text = reader.ReadToEnd();
}


(This is all part of the app that's attached at the top of this post. It basically outputs all the results to a richtextbox.)

A bit more complicated than last time, but not as bad. The main difference here is that we'll actually be writing TO the Request stream. This will insert the form values into the headers, which will allow the server to receive this data and process it. The trick is that for each value that you need to add, you use this syntax:

field1=value1&field2=value2&field3=value3

where field is the name of the input field, and the value is the value you want to send over to the server (ie. the text that would be entered into the textbox).

So if we were to run this method now, we'd see the text that we posted to the server (the text that was in the textbox of the app) in the richtextbox.

There is one more thing that we can do with this. Very often, in order to access certain areas of a site, you need to first log in. When you login, the server sends a cookie to the browser, and then for each subsequent request that is for authenticated users only, the browser send the cookie back to the server so that you can access those parts of the site. Here, we're acting like a browser, so we need to have the ability to get the cookie, retain it somehow, and then pass that on to the next request.

To demonstrate this, in the web app of this demo, there's a page called "..Home/PostWithCookie". When you access this page, it sends a cookie to the browser. Then, on that page there's a form identical to the first one. When you post back to the server though, it checks if the cookie is there. If it is, it outputs "Cookie Found" along with the cookie value, if not, it outputs "Cookie not found."

So back in our Windows App, we need a way to first access that first page that gets us our cookie, then we need to GET the cookie, and finally we need to pass the cookie on with the form post. Here's the code:



private CookieCollection GetCookies()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
String.Format("http://localhost:{0}/Home/PostWithCookie", port));
request.CookieContainer = new CookieContainer();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
return response.Cookies;
}

private void PostWithCookies()
{
CookieCollection cookies = this.GetCookies();
var request = (HttpWebRequest)WebRequest.Create(
String.Format("http://localhost:{0}/Home/PostWithCookie", port));
request.CookieContainer = new CookieContainer();
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string postData = String.Format("text={0}", String.IsNullOrEmpty(textBoxPost.Text)
? "somerandomemail@address.com" : this.textBoxPost.Text);
byte[] bytes = Encoding.UTF8.GetBytes(postData);
request.ContentLength = bytes.Length;
if (cookies != null)
{
request.CookieContainer.Add(cookies);
}

Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);

var response = request.GetResponse();
var stream = response.GetResponseStream();
var reader = new StreamReader(stream);
this.richTextBox1.Text = reader.ReadToEnd();
}


The first bit of code, the GetCookies method looks JUST like the original Screen Scrape method, however here we're actually grabbing the cookies. The trick is to new up a new CookieContainer before we do the request. Once we have a container, and we execute the request, we can get the cookies out of the response.

Now we have the cookie, but we aren't done. We want to pass this cookie back to the server when we post to the form. The only difference again here is that we have to new up a CookieContainer on the request, and add the cookies to that container. Once it's there, when you execute the POST, the cookies will get sent over as well.

The only way to really understand this all, is to download the sample, and mess with it. It's not very complicated, but you need to just mess with it a bit to understand. Once you do grasp it though, you'll see just how powerful this is. You can access many websites straight from within your app, and get the data right into your application.

C# Html Screen Scraping Part 1

1 comment:
This is the first post of a two part series.

Source Code: http://www.box.net/shared/i2p7t9kxkt

Very often, when a particular website has some information you'd like to use in your application, you'd see if they have some kind of API which you can use to query their data. However, it's very common for a website either to not have an API altogether, or not have that little bit of info you need made available in their API. What's done generally to get around this is a technique knows as "Screen Scarping". (Screen Scraping is a general term, not just for the web, but for the purpose of this blog, when I say Screen Scarping, I mean HTML Screen Scraping).

The general gist of it is this: when a browser contacts a site, an HTML document is sent back to the browser. The browser then has the (tedious) task of parsing out that HTML and rendering it out to the screen. End of the day though, the HTML is just a text file. What screen scraping basically is, you write an app that "acts" like a web browser, meaning it contacts the web site, downloads the HTML file into memory, at which point you're free to parse it out any which way you like and extract the data you need. In .NET this is incredibly easy to do, and I'll demonstrate a simple sample:


private string GetWebsiteHtml(string url)
{
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string result = reader.ReadToEnd();
stream.Dispose();
reader.Dispose();
return result;
}


Yup, that's pretty much it. First, you create a WebRequest object with the given URL. Then, you get a Response object out of that Request. Finally you get the response stream and read it with a StreamReader.

I attached a simple app so you can give it a whirl. Basically, it's a simple windows app with a textbox and a button. Enter any url in the textbox (make sure to write the full url including http://....) and hit the Go button. That will get you the entire HTML of that site, and display it in the richtextbox.

This is obviously a rough sample, make sure to add proper error handling, but other than that, it's pretty straightforward and real simple! The only thing to watch out for when scraping, is that your parsing code will rely on the HTML being formatted a VERY specific way. If the site changes in any way, your code WILL break.

This was a very simple post; in the next post, I'll take this much further, and demonstrate how we can actually POST to a server, and even get the cookies.

Monday, June 15, 2009

INotifyPropertyChanged - How to and when to?

1 comment:
Source Code: http://www.box.net/shared/nx8uj1rm1b

Databinding has always been fascinating to me; at first it really all looks like magic, how controls just track changes, and keep everything in sync. So much so, that very often I try to use it as little as possible, because I don't like using things I don't fully understand how they work. However, it does often save you from a lot of extra code, so I think it's very useful to explore it a bit, in particular the INotifyPropertyChanged interface.

Let's first start with a quick demo. Say you have a class, let's call is MyClass:



public class MyClass
{
public int MyProperty { get; set; }
}


Now let's say we have a Windows Form that has a DataGridView that we're using to bind to a BindingList of this type:



BindingList<MyClass> bindingList = new BindingList<MyClass>();
private void Bind()
{
bindingList.Add(new MyClass { MyProperty = 10 });
bindingList.Add(new MyClass { MyProperty = 20 });
bindingList.Add(new MyClass { MyProperty = 30 });
bindingList.Add(new MyClass { MyProperty = 40 });
this.dataGridView1.DataSource = bindingList;
}


This will work, and you'll have a DataGridView with one column called MyProperty with the rows 10,20,30,40. Very nice. Suppose however, that somewhere in the application, the contents of this list change (new values from database, or user input updated data, whatever..). You'll notice, that if your code applies changes directly to the BindingList, it will NOT reflect in the DataGridView:



public void UpdateList()
{
foreach (MyClass mc in this.bindingList)
{
mc.MyProperty = 100;
}
}


Just some simple code that changes all the MyProperty's to 100. You'll notice that these changes will NOT be reflected in the DataGridView. Well, the question becomes, how then do we have the changes reflected in the DataGridView? You COULD set the DataGridView's datasource to null and then rebind, but that's hacky and clumsy.

Enter the INotifyPropertyChanged interface. The interface has one property on it, and it's actually an event:



public interface INotifyPropertyChanged
{
// Summary:
// Occurs when a property value changes.
event PropertyChangedEventHandler PropertyChanged;
}


Looks quite simple, let's implement this now properly with a Person class. I've attached the source code to this post so you can download it and see for yourself. Here's the entire Person class:



public class Person : INotifyPropertyChanged
{

private string firstName;
private string lastName;
private int age;

public Person(string firstName, string lastName, int age)
{
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}

public Person()
{

}

protected virtual void OnPropretyChanged(string propertyName)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}


public string FirstName
{
get
{
return this.firstName;
}
set
{
if (this.firstName != value)
{
this.firstName = value;
this.OnPropretyChanged("FirstName");
}
}
}

public string LastName
{
get
{
return this.lastName;
}
set
{
if (this.lastName != value)
{
this.lastName = value;
this.OnPropretyChanged("LastName");
}
}
}

public int Age
{
get
{
return this.age;
}
set
{
if (this.age != value)
{
this.age = value;
this.OnPropretyChanged("Age");
}
}
}

#region INotifyPropertyChanged

public event PropertyChangedEventHandler PropertyChanged;

#endregion
}


The first thing you'll notice is that I implemented INotifyPropertyChanged. Then, in each setter of the properties, I call a method called "OnPRopertyChanged" which actually raises the event. The only downside of this, is that you can't use auto properties because the setters need to have logic. Also, since we'll be raising an event every time the value changes, it's worth putting in the extra if check:


if (this.firstName != value)
{
this.firstName = value;
this.OnPropretyChanged("FirstName");
}


just to make sure that the value actually changed.

I then created a simple Form that has a DataGridView that's bound to a BindingList<Person>. It also has a button, that when clicked, adds 5 years to everyones age.



public partial class Form1 : Form
{

private BindingList<Person> people;

public Form1()
{
InitializeComponent();
this.people = new BindingList<Person>();
this.PopulatePeople();
this.dataGridView1.DataSource = people;
}

private void PopulatePeople()
{
this.people.Add(new Person("Alex", "Friedman", 27));
this.people.Add(new Person("Jack", "Bauer", 45));
this.people.Add(new Person("Tony", "Almeda", 39));
this.people.Add(new Person("Chloe", "O'Brien", 37));
this.people.Add(new Person("Bill", "Buchanan", 50));
}

private void ChangeAges()
{
foreach (Person p in this.people)
{
p.Age += 5;
}
}

private void buttonChange_Click(object sender, EventArgs e)
{
this.ChangeAges();
}
}


If you run this, you'll notice that DataGridView does in fact get updated, even though I just manipulated the underlying list. I never actually touch the DataGridView itself. Internally, the BindingList checks to see if the class of type T (remember, BindingList is generic) implements INotfiyPropertyChanged. If it does, it hooks into that event, and when the event is raised, it updates itself.

The one thing to be careful is that when raising this event, you actually hardcode the name of the property. Personally, I wish there was a better way, but anything I've seen online so far had some serious overhead (like using the StackFrame to figure out which property is changing) so if someone knows of a better way, please let me know!

UPDATE: I recently blogged about a better approach to dealing with the INotifyPropertyChanged event that takes care of the hardcoded strings issue. Check it out here.

Thursday, June 11, 2009

Tweaking a DataGridView ComboBoxColumn to allow editing.

6 comments:
Let me first say this. I love the DataGridView and I think it's an awesome and very versatile control. It's highly customizable, and you can create a damn near excel-like application around it. Having said that though, anyone who's ever used a DataGridView knows just how "quirky" the stupid thing can be. Things that look like they should be simple, require clever hacks to implement.

Recently, I was creating an in-house app here at work, in which I needed a DataGridView with a ComboBoxColumn but with one wrinkle. Out of the box, the ComboBoxColumn doesn't support editing. Meaning, it acts like a ComboBox that has the DropDownStyle set to DropDownList (which doesn't allow the user to enter new values). We, however, did need to have the ability for the user to enter new values. I thought that this would be a simple property that I'd be able to set on the ComboBoxColumn. Yea, well there is no such property, so queue clever hack!

The first thing you need to do is hook into the DataGridView's EditingControlShowing event. This event fires when the actual ComboBox is "dropped down". The interesting thing is that the EventArgs has a property on it "Control" that can be cast to a standard WinForms ComboBox.

To demonstrate, I've created a simple Windows App that has a button on it and a DataGridView. It also has a method that just returns a list of strings that contains all the days of the week (needed something just for testing). When the button is clicked, the DataGridView gets populated with a ComboBoxColumn with all the days. Here's the entire code:



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

namespace DataGridViewComboBoxTesting
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.dataGridView1.EditingControlShowing += HandleEditShowing;
}

private void HandleEditShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
var cbo = e.Control as ComboBox;
if (cbo == null)
{
return;
}

cbo.DropDownStyle = ComboBoxStyle.DropDown;
cbo.Validating -= HandleComboBoxValidating;
cbo.Validating += HandleComboBoxValidating;
}

private void HandleComboBoxValidating(object sender, CancelEventArgs e)
{
var combo = sender as DataGridViewComboBoxEditingControl;
if (combo == null)
{
return;
}
if (!combo.Items.Contains(combo.Text)) //check if item is already in drop down, if not, add it to all
{
var comboColumn = this.dataGridView1.Columns[this.dataGridView1.CurrentCell.ColumnIndex]
as DataGridViewComboBoxColumn;
combo.Items.Add(combo.Text);
comboColumn.Items.Add(combo.Text);
this.dataGridView1.CurrentCell.Value = combo.Text;
}
}

private void button1_Click(object sender, EventArgs e)
{
var cboColumn = new DataGridViewComboBoxColumn
{
Name = "ComboBox",
HeaderText = "Combo Box Column"
};

foreach (var day in this.GetListOfStrings())
{
cboColumn.Items.Add(day);
}

this.dataGridView1.Columns.Add(cboColumn);
}

public IEnumerable<string> GetListOfStrings()
{
foreach (var day in Enum.GetValues(typeof(DayOfWeek)))
{
yield return day.ToString();
}
}
}
}


As you can see, in the HandleEditShowing method, we can get access the the underlying ComboBox itself, and set the DropDownStyle property right there. We then do a little more hackery so that when the user enters a new value, we can add it to all other ComboBox's in that column. We do that by hooking into the ComboBox's Validating event (first we unhook it in case we're already hooked into it, so that our event handler doesn't get called more than once).


private void HandleEditShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
var cbo = e.Control as ComboBox;
if (cbo == null)
{
return;
}

cbo.DropDownStyle = ComboBoxStyle.DropDown;
cbo.Validating -= HandleComboBoxValidating;
cbo.Validating += HandleComboBoxValidating;
}


The event handler then looks like this:



private void HandleComboBoxValidating(object sender, CancelEventArgs e)
{
var combo = sender as DataGridViewComboBoxEditingControl;
if (combo == null)
{
return;
}
if (!combo.Items.Contains(combo.Text)) //check if item is already in drop down, if not, add it to all
{
var comboColumn = this.dataGridView1.Columns[this.dataGridView1.CurrentCell.ColumnIndex] as DataGridViewComboBoxColumn;
combo.Items.Add(combo.Text);
comboColumn.Items.Add(combo.Text);
this.dataGridView1.CurrentCell.Value = combo.Text;
}
}


Simple. We just check if it's already in the list, if it's not then add it to the combo box as well as add it to all other combo boxes.

Here's a link to the source code. In the code I also created a class called DataGridViewComboBoxColumnEx which basically inherits from DataGridViewComboBoxColumn and encapsulates all this hackery nicely. You just use it as you normally would but it allows editing.

Source code: http://www.box.net/shared/73bmzmv1r6

Tuesday, June 9, 2009

How do closures / captured variables work under the hood?

No comments:
First, a little disclaimer. I'll be using 3.0 syntax with Lambda's but this has been around since .NET 2.0 and anonymous methods.

Ok, so first a little demonstration:



namespace ClosureDemo
{
public delegate void StuffDoer();

class Program
{
static void Main(string[] args)
{
var stuffDoerDelegate = GetDelegate();
stuffDoerDelegate();
stuffDoerDelegate();

Console.ReadKey(true);

}

private static StuffDoer GetDelegate()
{
int counter = 1;
StuffDoer result = () =>
{
counter++;
Console.WriteLine(counter);
};
result();
return result;
}

}
}


Simple little app. First, I create a delegate type called "StuffDoer" that has a return type of void, and takes no parameters. Then, I have a private method that news up a StuffDoer delegate, and attaches an anonymous method to it. Here's the interesting thing to note though: I declared a variable called counter outside of the anonymous method. The obvious question that comes to mind is how? Shouldn't counter be outside of scope? If you didn't declare this as an anonymous method, but rather as a concrete method:



private static StuffDoer GetDelegate()
{
int counter = 1;
StuffDoer result = new StuffDoer(DoStuff);
return result;
}

private static void DoStuff()
{
counter++;
Console.WriteLine(counter);
}


This obviously wouldn't compile because counter is undefined in the DoStuff method. So how can it work in the anonymous method? Furthermore, you'll notice, that if you run this program, it prints out 2, 3 and 4 which shows us that the counter variable somehow stuck around?? How? We declared it once inside our GetDelegate method, shouldn't it have been lost after we left that method? How did it retain it's state?

This is knows as "closures" or "captured variables" and was always just one of those "black magic it just works" kinda thing for me. I researched it, thought I kinda understood it, but never QUITE got it. Recently, however, I picked up a copy of Jon Skeet's C# In Depth book (I CANNOT stress enough how great this book is! I'm only halfway through, didn't even start with the C# 3.0 / .NET 3.5 stuff yet, and already I've learned tons of stuff. I HIGHLY recommend it!) and it opened my eyes as to what exactly is going on under the covers. I'll admit, it may not really matter at the end of the day, you could just stick with the "it just works" attitude, but I like trying to understand how stuff works under the covers.

The first thing to understand is that the compiler is smart. Very smart. It notices that the counter variable is being "captured" and does some funky stuff for us. If you open reflector, you can see what exactly happened here:



You'll notice that there's a class there that I never created. You'll see it there as "<>c__DisplayClass1". And if you look at the code, it looks something like this:



[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
// Fields
public int counter;

// Methods
public void <GetDelegate>b__0()
{
this.counter++;
Console.WriteLine(this.counter);
}
}



Ok, we're getting somewhere; a class was created for us with the counter variable as a public member, as well as a public method that looks just like our anonymous method. Very cool.....but how exactly does that help us? Now, if we look back in our "GetDelegate" method in Reflector, this is what we see:



private static StuffDoer GetDelegate()
{
<>c__DisplayClass1 CS$<>8__locals2 = new <>c__DisplayClass1();
CS$<>8__locals2.counter = 1;
StuffDoer result = new StuffDoer(CS$<>8__locals2.<GetDelegate>b__0);
result();
return result;
}


Looks like a mess with all the compiler generated stuff, but we can finally see the big picture. I'll rewrite the code in "plain english" so you can see what's going on:

First, I create a counter class: (this is instead of the "<>c__DisplayClass1" the compiler generated.)



public class CounterClass
{
public int counter;

public void DoSomething()
{
counter++;
Console.WriteLine(counter);
}
}


Then, back in the Program.cs, let's change the GetDelegate method to this:



private static StuffDoer GetDelegate()
{
CounterClass c1 = new CounterClass();
c1.counter = 1;
StuffDoer result = new StuffDoer(c1.DoSomething);
result();
return result;
}


Here's the key. As I've pointed out in the past, delegates are objects, and can hold references to other objects. So, what's happening here is, an instance of our CounterClass is created, and we pass in one of it's methods to a new instance of the StuffDoer delegate. This now causes the delegate to hold a reference to this CounterClass object. Then, every time after that, when you invoke the delegate, it's still holding a reference to the same object it had in the beginning so you're constantly calling the methods on the same object!

Now it all makes sense; that's how it can reference the counter variable inside the anonymous method, because it's actually a method in a class that's referencing it's own public member. And now also we understand how it maintains state, because it's just a regular object that's being kept around. Smart smart compiler :)

Wednesday, June 3, 2009

Lesson learned....RTFM!

3 comments:
A few weeks ago, I was tasked with writing a site map generator for our new site at work that uses ASP.NET MVC. When using ASP.NET MVC Controllers have "Actions" that map to URL's. For the sake of this blog point, all that's important to know is that generally Actions are methods that return an ActionResult object. So, the idea was, in order to generate the site map correctly, I would use reflection to inspect the entire assembly, and any method that returned an ActionResult would be entered into the site map with the correct XML.

The catch however was that in many instances, the return type of our Action's weren't actually ActionResult objects, but rather classes the derived from ActionResult. (Some that are built into ASP.NET MVC and some custom ones.) So, I quickly realized I needed a method that you can pass in a type, along with another type, and the method would tell you if anywhere up the inheritance chain, type1 inherits from type2.

My first thought was "Perfect! I'll just use recursion!" This quickly got me excited, because it's not every day you get to use recursion in a useful piece of production code, much less when it came to reflection. So, I ended up writing an extension method that crawls up the inheritance chain recursively and it worked perfectly. Here's the code:

public static class TypeExtensions
{
public static bool InheritsFrom(this Type type, Type baseType)
{
if (baseType == null || type == null)
{
return false;
}

if (type.BaseType == baseType)
{
return true;
}

return type.BaseType.InheritsFrom(baseType);
}
}


Basically, the Type class has a handy property called BaseType which basically gives you the BaseType (duh!). If the Type is object, then BaseType is null, in which case we know we've reached the top of the inheritance chain, and we're done. To test this method out, let's whip up some demo code:



public class MyMemoryStreamBase : MemoryStream
{

}

public class MyMemoryStreamChild : MyMemoryStreamBase
{

}

public class MyMemoryStreamGrandChild : MyMemoryStreamChild
{

}
Basically, I've created a nice Inheritance chain that goes up to MemoryStream -> Stream -> MarshalByRefObject and finally object. Here's how you can test it:


Type type = typeof(MyMemoryStreamGrandChild);
bool result = type.InheritsFrom(typeof(MarshalByRefObject));
Console.WriteLine(result);

If you run this, the result will be True, proving that my cute little method worked, and I was all happy.

Fast forward a few weeks, and while browsing StackOverflow, I came across a question regarding reflection and BaseType's when some dude posts a link to this:

Type.IsSubClassOf(..)

Yeah, that's right! It's built right into the .NET Framework! Now obviously it's impossible to know of every method in the framework, but as soon as I thought of the need, and that it involved recursion, I simply whipped out Visual Studio and started coding, without actually taking a moment and thinking, hey research this first! You can't be the FIRST person to come across this very issue!

Feeling completely beat, I was just curious at this point as to how it's implemented in the Framework. Were they also using recursion, or did they have some other ingenious way of doing this. Well here's how they did it:



public virtual bool IsSubclassOf(Type c)
{
Type baseType = this;
if (baseType != c)
{
while (baseType != null)
{
if (baseType == c)
{
return true;
}
baseType = baseType.BaseType;
}
return false;
}
return false;
}

Yea, no recursion, just a simple while loop. At this point, I was just curious in general as to which method is quicker. So, some quick benchmarks:




public void CompareMethodsSpeed()
{
Stopwatch watch = new Stopwatch();
Type type = typeof(MyMemoryStreamGrandChild);
Type baseType = typeof(MarshalByRefObject);
watch.Start();
for (int i = 0; i < 100000; i++)
{
type.InheritsFrom(baseType);
}
watch.Stop();
Console.WriteLine("My way took: {0} ticks.", watch.ElapsedTicks);

watch.Reset();

watch.Start();
for (int i = 0; i < 100000; i++)
{
type.IsSubclassOf(baseType);
}
watch.Stop();
Console.WriteLine("Their way took: {0} ticks.", watch.ElapsedTicks);
}


Then I ran this one my machine and the results were:

My way took: 107433 ticks.
Their way took: 41684 ticks.

So yea, I got my butt whooped!! I'll chalk this one up to experience.

Moral of the story? Two things. First, not just because you CAN do it with recursion, does that mean you SHOULD do it that way. Second, RTFM!! Chances are, MS has more time to test various ways of doing certain things, so double check that something is in the Framework before rolling your own.

The only one thing I'll say in my (somewhat weak) defense is that InheritsFrom is a MUCH better name for this method than IsSubslassOf IMO. So yea, name your methods better MS!!

Tuesday, June 2, 2009

Creating a Splash Screen in .NET with a progress bar.

9 comments:
EDIT: I've added a link to the source code: http://www.box.net/shared/xbo9xvlguu

Many times an application needs to do many time consuming operations at start-up. Sometimes you need to read data from a database, sometimes you may need to retrieve some data from a web service. When this happens, it's often useful to display a "Splash Screen" to the user, with a company logo or something, along with a progress bar to indicate how much longer it will take for the app to load. While it may sound simple at first, it can be a bit tricky; if you simply show a screen, and do your time consuming operations, your UI will hang and your progress bar will never update. Therefore, there's some threading involved (not too much, don't get scared!), so I'll demonstrate a simple example here.

Start off by creating a simple Windows Forms project. Once it's loaded, add another windows form (besides for the Form1 that's already there) and call it "SplashScreen". To get the look and feel right, let's set some properties:

  • FormBorderStyle: None
  • TopMost : True
  • StartPosition: CenterScreen
Now, in the properties window, find the BackgroundImage property and click the little elipsis {...} and select a picture from your hard drive. I also then changed the BackgroundImageLayout property to None but you can do whatever you want. Then, add a progress bar to the bottom of the form, and set the Dock property to Bottom. Here's what my splash screen looks like in the designer: (not sure why I chose a Halo picture....)

Now, we need to give access to someone outside of this class to update the progress (the progressBar is a private member and can't be accessed.) Here's the problem; if we simply wrap the progress bar's Value property in our own getter/setter like this:



public int Progress
{
get
{
return this.progressBar1.Value;
}
set
{
this.progressBar1.Value = value;
}
}

while you can do that, remember, this splash screen will be shown in a seperate thread. If you then try to access this property from your main thread, you'll get an InvalidOperationException that "Cross-thread operation not valid: Control 'progressBar1' accessed from a thread other than the thread it was created on." So, in order to be able to set any of the UI elements from another thread, we need to call the form's Invoke method which takes a delegate. Here's the complete code for the SplashScreen class:


using System.Windows.Forms;

namespace SplashScreenTesting
{
public partial class SplashScreen : Form
{
private delegate void ProgressDelegate(int progress);

private ProgressDelegate del;
public SplashScreen()
{
InitializeComponent();
this.progressBar1.Maximum = 100;
del = this.UpdateProgressInternal;
}

private void UpdateProgressInternal(int progress)
{
if (this.Handle == null)
{
return;
}

this.progressBar1.Value = progress;
}

public void UpdateProgress(int progress)
{
this.Invoke(del, progress);
}
}
}

As you can see, we created a delegate that we'll use to invoke the update to the progress bar. (The reason why I have a null check for this.Handle is because I was getting an exception right at the start up that the Handle wasn't created yet.)

Ok, now let's create a class that simulates a time consuming operation. Basically, it just calculates Math.Pow for numbers 1 - 100 raised to the 1 - 500,000th power. Every time we move on to another outer number (the 1 - 100) we raise an event that reports progress. Once it's done, we raise an event that we're done. Here's the complete class:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SplashScreenTesting
{
public class Hardworker
{
public event EventHandler<HardWorkerEventArgs> ProgressChanged;
public event EventHandler HardWorkDone;

public void DoHardWork()
{
for (int i = 1; i <= 100; i++)
{
for (int j = 1; j <= 500000; j++)
{
Math.Pow(i, j);
}
this.OnProgressChanged(i);
}

this.OnHardWorkDone();
}

private void OnProgressChanged(int progress)
{
var handler = this.ProgressChanged;
if (handler != null)
{
handler(this, new HardWorkerEventArgs(progress));
}
}

private void OnHardWorkDone()
{
var handler = this.HardWorkDone;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}

public class HardWorkerEventArgs : EventArgs
{
public HardWorkerEventArgs(int progress)
{
this.Progress = progress;
}

public int Progress
{
get;
private set;
}
}
}


I also created a custom event args so that we can pass the progress on to the subscriber of our ProgressChanged event. (As a side note, if you're wondering about the strange assignement taking place when raising the event, see Eric Lippert's blog on the subject.)

Now, on to the main part of the app; the displaying of the splash screen. In the Form1's load event, we'll spawn off another thread to actually display the splash screen and then on the main thread we'll do our "Hard Work". Once the HardWorker has reported that the progress is complete, we'll dispose of the splashscreen and display the main Form. Here's the code, I'll try my best to explain:

using System;
using System.Windows.Forms;
using System.Threading;

namespace SplashScreenTesting
{
public partial class Form1 : Form
{
private SplashScreen splashScreen;
private bool done = false;
public Form1()
{
InitializeComponent();
this.Load += new EventHandler(HandleFormLoad);
this.splashScreen = new SplashScreen();
}

private void HandleFormLoad(object sender, EventArgs e)
{
this.Hide();

Thread thread = new Thread(new ThreadStart(this.ShowSplashScreen));
thread.Start();

Hardworker worker = new Hardworker();
worker.ProgressChanged += (o, ex) =>
{
this.splashScreen.UpdateProgress(ex.Progress);
};

worker.HardWorkDone += (o, ex) =>
{
done = true;
this.Show();
};

worker.DoHardWork();
}



private void ShowSplashScreen()
{
splashScreen.Show();
while (!done)
{
Application.DoEvents();
}
splashScreen.Close();
this.splashScreen.Dispose();
}
}
}

In the constructor we just hook into the Load event and new up the SplashScreen. Then, in the Load event handler, we first hide the current form, because we don't want that to be seen just yet. We then create a Thread and pass in a delegate to our ShowSplashScreen method. The show splash screen method is what's actually going to be run on a seperate thread. First, it displays the SplashScreen. Then, it just sits there in a constant loop waiting for the "done" bool to be set to true. The key ingredient here is the call to Application.Doevents(). I think Microsoft does a good job explaining what this does so I'll let them do that talking:

When you run a Windows Form, it creates the new form, which then waits for events to handle. Each time the form handles an event, it processes all the code associated with that event. All other events wait in the queue. While your code handles the event, your application does not respond. For example, the window does not repaint if another window is dragged on top.

If you call DoEvents in your code, your application can handle the other events. For example, if you have a form that adds data to a ListBox and add DoEvents to your code, your form repaints when another window is dragged over it. If you remove DoEvents from your code, your form will not repaint until the click event handler of the button is finished executing. For more information on messaging, see User Input in Windows Forms.


Basically, it allows other events to be taken care of, even though the current procedure is blocking execution. This allows our progress bar to be updated.

Back in the form load, we then new up our HardWorker and hook into it's events. (I'm using the more terse Lambda syntax, see my previous blog post on the subject here for more information.) Basically, every time the HardWorker reports progress, we update our progress bar. Then when it's done, we set our done flag to true, and show the main form. Finally, we actually kick it off with a call to DoHardWork();

Try it out and run it. It's actually kinda neat to see it in action. This is obviously a very rough example, but it should give you a basic idea on how to get this done.