Gavin Stevens's Blog

the ramblings of another developer....

  Home  |   Contact  |   Syndication    |   Login
  34 Posts | 0 Stories | 57 Comments | 212 Trackbacks

News

Archives

Post Categories

Maybe I need to re-subscribe to MSDN magazine or something, it seems there are soooo many things you can learn about programming, there is never enough time..  If you spend all your time programming, you never have time to learn about  new stuff.  And even if you learn a ton, things seem to slip by...  It seems everything most of us developers know is because we had to do something at sometime in the past and had to find a way to do it.  If the ways and means we do things are the correct way, who knows..  If it works, great!!!

When you first start programming you start to run into state management and storage issues. You always run into a problem that requires that you store something that something else can make use of.  Say for example you have a list of Cities that you read from a file on disk. So, you can create a new city object, and make a Collection of Cities in your application somewhere to load them into.  As a beginner programmer, I would always start a windows app with some "Control" class which would be my "everything class" something like this:

Public class control
{

private collection cities
private frmForm1 form1
private frmForm1 form2

private void loadcities(){load the file, store the values in the collection}

public void GO()
{
 loadcities();
 form1 = new frmForm1(cities);
 form1.showdialog(); 

 form2 = new frmForm2(cities, form1.SelectedCity);
 form2.showdialog();

}

}

While I agree this is pretty bad...  for a beginner long ago, it served its purpose.  I was able to load the city list once and query state on one form from another without having to read/write anything else to the disk, Or store anything anywhere else for that matter.  I found that by creating this "control" class I had a global place that I could store things and something that would know about both forms.

This type of design leads to a very strictly coupled application.  Nothing can ever change on either form, or in my control class without bad consequences.  Plus you can't develop object oriented, interface based stuff this way...

Web Developers have been lucky since the asp days as they have a global "state bag", ie "session"  they can stick things in while navigating from page to page.  But, as far as I knew there was nothing like this for a windows developer, I would always store state in a scenario like the above example, or stick things in a database or the registry for storage.

Enter the AppDomain and the Thread.

While I was always aware these objects existed, they didn't seem to be something you mess with that often. I had no idea that you could store things in them and provide a global, or thread specific "state bag".  I can load my cities list and stick it on the Thread Context.

Saving Data to the Thread:

Thread.AllocateNamedDataSlot("CitiesList");

LocalDataStoreSlot myData;
myData=Thread.GetNamedDataSlot("CitiesList");
Thread.SetData(myData, cities);

Getting it back out:

LocalDataStoreSlot myData;
myData=Thread.GetNamedDataSlot("CitiesList");
Collection cities=(Collection)Thread.GetData(myData);

Finally, we need to free the data slot that we allocated in the beginning of our application.

Thread.FreeNamedDataSlot("CitiesList");

This allows you to take an object and stick it in the Current thread's local storage.  You can also do the same thing with the AppDomain, if you need to access your data with mutiple threads of execution.  Just make sure you lock, unlock the objects when your thread is accessing them so you don't mess up your data by having mutiple thread try to change the values at the same time.

from MSDN:
 // appdomain setup information
        AppDomain currentDomain = AppDomain.CurrentDomain;

        //set predefined system variable application name
        String dataName = "APP_NAME";
        String setappname = "MyApplication";
        currentDomain.SetData(dataName, setappname);

        //Create a new value pair for the appdomain
        String dataValue = "ADVALUE";
        Int32 advalue = 6;
        currentDomain.SetData(dataValue, advalue);

        //get the value specified in the setdata method
        Console.WriteLine(" ADVALUE is: " + currentDomain.GetData("ADVALUE"));

        //get system value specified at appdomainsetup
        Console.WriteLine("System value for application name:" + currentDomain.GetData("APP_NAME"));


There are some samples and better descriptions than I can give here:

http://msdn2.microsoft.com/en-us/library/system.threading.thread.setdata.aspx
http://msdn2.microsoft.com/en-us/library/system.appdomain.setdata(vs.71).aspx

I'm sure alot of you guys know about this stuff, but maybe someone can learn something... 

If any of you more seasoned guys have some best practices for doing this stuff, please feel free to share.

Cheers!

posted on Friday, July 27, 2007 1:50 PM