OdeToCode IC Logo

Visual Studio 2005 Notes

Saturday, August 14, 2004 by scott
 It’s experimentation day.

I was looking at some web forms with Trace enabled in ASP.NET 2.0, looked at the ViewState size, and remembered reading about some view state enhancements in 2.0. So I did a little experiment.

In ASP.NET 1.1 I rendered ‘SELECT * FROM pubs..employee’ in a DataGrid control using all the default settings (auto-generated columns, ViewState enabled). The resulting page used 26,241 bytes.

In ASP.NET 2.0 I rendered ‘SELECT * FROM pub..employee’ in a DataGrid control, again using all the defaults. The resulting page used 16,089 bytes. A difference of 10,152 bytes, which is quite a bit if you insist on enabling ViewState on a DataGrid. The same experiment using the new GridView control, with sorting enabled, ran 17,996 bytes.

For anyone who has not seen the GridView in action, Dino Espisito has an article: Move Over DataGrid, There's a New Grid in Town!


I noticed in the trace there is a new PreInit event in the page life cycle. This makes me wonder if we might need a PrePreInit event in ASP.NET 3.0? Perhaps a BeforePreInit?  

It turns out PreInit is the event to grab in order to dynamically change the personalization, theme, or master page settings (it was also time to get in touch with my kindler, gentler, VB side, but don’t tell anyone):

Private Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit

    MasterPageFile = "~/FunkyDoodleLayout.master"

End Sub

Setting the MasterPageFile property after the PreInit event only throws an exception. Paul Wilson has a good introduction to the Master Page feature: Standardize Your Site Fast With Master Pages.


Somehow, in the middle of this, I began surfing and read about Boston’s Great Molasses Flood of 1919. I’ve never heard of this and first thought it was an urban myth, but it’s not. A 30 foot high wall of molasses moving at 35 miles per hour.  


The code expansion in C# is quite good. I type the ‘using’ keyword, hit the TAB key, and the IDE inserts a code block for me:

using (resource)
{
 
}

The word resource appears in yellow and is selected, so I just need to type in the expression. If you expand a for statement, then the initializer is highlighted. As soon as you change the variable name in the initializer, the IDE changes the variable name in the expression and iterator to match, saving quite a few keystrokes.

What is interesting is the C# code snippets center around simple block statements (lock, using, for, do). The VB snippets seem to include entire algorithms. You choose to “Insert Snippet…”, then chose “Processing Drives, Folders, and Files”, then “Parse Column Data In a Text File”, and the IDE spits out the following code, where the file name and delimiters array are replaceable by tabbing through the snippet and typing (this is hard to describe, you just have to try it):

' This example parses a file with this structure.
' Line1Column1, Line1Column2, Line1Column3
' Line2Column1, Line2Column2, Line2Column3
' Line3Column1, Line3Column2, Line3Column3
' Line4Column1, Line4Column2, Line4Column3

Dim parser As TextFieldParser
parser = My.Computer.FileSystem.OpenTextFieldParser("C:\TextFile.txt")
parser.Delimiters = New String() {","}
Dim fields() As String
While Not parser.EndOfData
    Try
        ' ReadFields reads one line of data from the file.
        ' Array 'fields' contains one string element for each column.
        fields = parser.ReadFields
    Catch ex As MalformedLineException
        MsgBox("Error on line: " & ex.LineNumber)
        Throw ex
    End Try
End While
parser.Close()

As I’ve said before, someday I’m going to come home and find my cat has written a Tetris clone by sleeping on my keyboard. In VB of course.

I Can't Take The Heat

Thursday, August 12, 2004 by scott
The air conditioner is broken at work and I am now sitting in the world’s only sauna that requires business casual dress. Like a fine Pinot Grigio, I must be properly chilled before I can reach my full potential. It’s too hot here to debug software, so I’m going to blog.

I work in a government technology “incubator” building, meaning there are a dozen startup companies around here and we share a common copier room, common break room, and common conference rooms. The key word here is ‘government’. I have complete faith the county maintenance people feel my discomfort and will rush to fix the air conditioning problems just in time for the first major snowfall of the year.

In other news, I’ve been under a lot of peer pressure lately. Test driven development is a great way to write quality code, but sometimes good old fashioned peer pressure works just as well. Why just recently I opened the latest build notes to look at the list of file diffs. Imagine my surprise when I see:

File Check-in Date Version Check-in By Comment
VisitSearch.ascx.cs 8/8/2004 11:42:36 AM 2 Plall Fix Scott’s sloppy code.
Ouch. Now I have another excuse not to write code. Not only is this room so hot I feel I should be wearing sunscreen lotion, but if I slip up in these conditions my work is subject to public humiliation. Time to find cooler air….

Reporting Services Security

Wednesday, August 11, 2004 by scott

For anyone facing authentication or authorization errors in a Reporting Services environment, or just looking for some introductory material, I've posted two new articles to OdeToCode:

Introduction To Role-Based Security In SQL Server Reporting Services

Authentication, Role-based Security, and Reporting Services Web Services

If you give them a read, please let me know if you think they are easy to understand, and please let me know if they contain any errors.

The Telephone Is Ringing (Small Company Life)

Saturday, August 7, 2004 by scott

Working for a startup means we forego some ‘luxuries’ of business life, like having a receptionist in the office to answer phones. We all have to answer the phone. I purposefully keep my phone at a location out of arm’s reach, giving everyone else who keeps a phone close by the first chance at answering.

There are a few reasons I try to avoid the phone.

First, I get tired of talking to the cold-calling photocopier sales people. There is nothing worse than being neck deep in a database and having one of these overly cheerful people call and tell me how I need a photocopier with a re-circulating automatic document feeder. Yes, of course, our office could use a re-circulating automatic document feeder, but what the office really needs is a new laser printer with a warm up time of less than 15-minutes. Unless they are giving away a free photocopier, talking about it over the phone is a waste of time.

To understand another reason why I avoid the phone, I have to give you some background. The company founder, who works part-time in the office, is a practicing physician - a gastroenterologist to be exact. I also have to tell you his name, because you might find this amusing. His name is, and I swear I am not making this up, Dr. Butt.

On occasion, the doctor will call a patient from the office phones to discuss their condition, or their colonoscopy results. Some patients, like the ones who are stark raving mad hypochondriacs, will see the phone number on their caller ID and write the number down. They think if they call this number, they will talk to a doctor or someone with medical training. When they do call, they get people like me, who have no medical training and feel lightheaded when I see a needle.

Telling some people that you are not qualified to give them medical advice does little to slow them down. Some people don’t seem to want advice, actually. What they want is just to be able to describe their problems to another human in graphic detail. This includes the finer facts of their fecal incontinence, or their irritable bowels, or the blood in their stool.

Quite frankly, I’m not paid enough to listen to this sort of talk on the phone. I’ll ask the person to please hold, and forward the call to our sales person. Sales people can talk about anything, even before right before lunch.

Rush

Saturday, August 7, 2004 by scott

I had to miss this month’s CMAP user group meeting – but for good reason. Rush was playing at the Nissan Pavilion in VA. I scored tickets next to the soundboard area. The person I sat the closest to had 3 Alienware laptops setup, but only one of which I could see clearly. It was running Windows XP. I saw a splash screen for software by the name of TouchMixer. Google tells me the software is made by Derivative Inc. This fellow controlled all of the video effects on the big screen.

I’ve seen some good performances the first 7 months of this year:

The next 4 months look pretty bleak.

Language Lawyers (and Nasal Demons)

Friday, July 30, 2004 by scott
As soon as a development language has an official specification behind it, the first language lawyer appears. If you’ve never seen one in action, they are the type who can rattle off section and paragraph numbers from a specification while explaining the bizarre behavior of some code snippet. You might see them write something along the lines of:

The values of a and b are automatically promoted back to int [6.2.1.1/ 3.2.1.1], which is then the type of the result of the / operator [6.2.1.5/3.2.1.5]. Since -32768 is exactly divisible by -1, and the result of 32768 is representable in the type int, the division must yield this value.

Nearly every language with a specification will describe situations with “undefined behavior”. Undefined behavior means there is something so horribly screwed up in the code, or in the data, that the program is probably going to crash spectacularly. Except specifications never use the word ‘crash’. Many of them, including the C# spec, will use the more dignified phrase: “unpredictable results”.

Now language lawyers, not really being lawyers, have a sense of humor. Since the phrase “unpredictable results” leaves the outcome so open-ended, they will say undefined behavior could, in fact, lead to demons flying out of your nostrils.

The first apparent reference to demons and noses came in a 1992 post to the comp.std.c newsgroup. The post contains many paragraph and section number references to the C language specification, but ends with this little gem:

In short, you can't use sizeof() on a structure whose elements haven't been defined, and if you do, demons may fly out of your nose.

The phrase caught on.

In the mid 90’s I was maintaining a C code base intended for both an 8 bit Hitachi chip and the PC, so I was interested in writing portable ANSI C programs and followed the comp.std.c and comp.lang.c newsgroups. I don’t know how many times someone would come along and post code which started like this:

void main (void)

As soon as the above line appeared the language lawyers appeared in force. You could look at the code, and see it was only one semi-colon away from curing world hunger, but it didn’t matter, because the response was invariably something like:

The Standard says that declaring main as returning void invokes undefined behavior. Beware the nasal demons.

Although sometimes the lawyers would make other amusing comments:

if you write:

void main (void) 

it's *possible* (under the rules of C) that your computer will pogo round the room whistling the star spangled banner. It's very unlikely, but C isn't interested in "likely".

Whenever I was having a really bad day, I’d write a program with main returning void just to see what would happen. I tried it with the Microsoft C compiler, the Borland C compiler, the Intel C compiler, and the now defunct Boston Systems Office C compiler. I was hoping to create a horrible, slimy demon who I could train to stand at my office door and terrify people trying to enter with requirements documentation in hand. Not only did I never get a demon, the programs always worked without any errors. Shows you what the language lawyers know.

In any case, I’m hoping to find some good examples of undefined behavior in C# or VB so I can try to invoke nasal demons from .NET. I imagine it will be much harder to do with a managed runtime in place, but if you know of any opportunities, please let me know.

Static Constructors Are Not Miracle Workers

Thursday, July 29, 2004 by scott
The CLR guarantees a type initializer (static constructor) will execute only once for any given type. This simplifies my life, because I don’t need to worry about multiple threads inside of a static constructor. Take for example the following program:

static void Main(string[] args)
{
   Thread threadA = new Thread(new ThreadStart(TouchFoo));
   threadA.Name = "Thread A";
 
   Thread threadB = new Thread(new ThreadStart(TouchFoo));
   threadB.Name = "Thread B";
 
   threadA.Start();
   threadB.Start();
   
   threadA.Join();
   threadB.Join();
}
 
static void TouchFoo()
{
   Foo.SayHello();
}
 
class Foo
{
   static Foo()
   {
      Thread.Sleep(1000);
      Console.WriteLine("Foo .cctor on thread {0}", Thread.CurrentThread.Name);
   }
 
   static public void SayHello()
   {
      Console.WriteLine("Hello From Foo");
   }
}

In this program, Thread A will probably get the first chance to execute TouchFoo. In doing so, the CLR recognizes the static constructor for Foo has not been executed and sends Thread A into the constructor, which puts the thread to sleep for 1000 ms. The sleeping period allows Thread B to run. Thread B arrives inside of TouchFoo, and again the CLR recognizes the static constructor for Foo has not completed executing. This time however, the CLR knows somebody is working inside of the constructor, and it blocks Thread B until Thread A finishes Foo’s constructor. Typically then, this program would produce the following output:

Foo .cctor on thread Thread A
Hello From Foo on thread Thread A
Hello From Foo on thread Thread B

No matter how many threads we throw into the mix, the CLR will only allow one thread inside of the static constructor. Of course this isn’t magic, there has to be some thread synchronization (a lock) taken by the CLR before entering the static constructor.

Where there are locks, there is the possibility of a deadlock. So what happens if we try to put the runtime into a bind by feeding it code that should deadlock? Do you think the following program will execute, or will I need to kill it from task manager?

class Class1
{
   [STAThread]
   static void Main(string[] args)
   {
      Thread threadA = new Thread(new ThreadStart(TouchFoo));
      threadA.Name = "Thread A";
      
      Thread threadB = new Thread(new ThreadStart(TouchBar));
      threadB.Name = "Thread B";
 
      threadA.Start();
      threadB.Start();
 
      threadA.Join();
      threadB.Join();
   }
 
   static void TouchFoo()
   {
      string s = Foo.Message;
   }
 
   static void TouchBar()
   {
      string s = Bar.Message;
   }
}
 
class Foo
{
   static Foo()
   {
      Console.WriteLine("Begin Foo .cctor on thread {0}", Thread.CurrentThread.Name);
      Thread.Sleep(5000);
      Console.WriteLine("Foo has a message from Bar: {0}", Bar.Message);         
      message = "Hello From Foo";
      Console.WriteLine("Exit Foo .cctor on thread {0}", Thread.CurrentThread.Name);
   }
 
   static public string Message
   {
      get { return message; }
   }
 
   static string message = "blank";
}
 
class Bar
{
   static Bar()
   {
      Console.WriteLine("Begin Bar .cctor on thread {0}", Thread.CurrentThread.Name);
      Thread.Sleep(5000);
      Console.WriteLine("Bar has a message from Foo: {0}", Foo.Message);         
      message = "Hello From Bar";
      Console.WriteLine("Exit Bar .cctor on thread {0}", Thread.CurrentThread.Name);
   }
 
   static public string Message
   {
      get { return message; }
   }
 
   static string message = "empty";    
}

Notice in this example, the static constructor for Foo references Bar’s Message property, and vice versa. This produces the following scenario:

Thread A starts and eventually enters the static constructor for Foo. After a writing to the screen, the thread goes to sleep for 5000 ms. Thread B now has a chance to run and eventually enters the constructor for Bar, prints a message and goes to sleep.

Next, Thread A wakes up and finds it needs information from an un-initialized Bar, but it cannot run the constructor because Thread B has it locked. Thread B awakes and needs information from Foo, but it cannot run the Foo constructor because Thread A has it locked. Thread A needs the lock held by Thread B, and Thread B needs the lock held by Thread A. Classic deadlock!

As it turns out, the CLI specification addresses this issue in section 9.5.3.3 of Partition II, entitled “Races and Deadlocks”:

Type initialization alone shall not create a deadlock unless some code called from a type initializer (directly or indirectly) explicitly invokes blocking operations.

So if we don’t have a deadlock, what happens? Here is the output on my machine:

Begin Foo .cctor on thread Thread A
Begin Bar .cctor on thread Thread B
Bar has a message from Foo: blank
Exit Bar .cctor on thread Thread B
Foo has a message from Bar: Hello From Bar
Exit Foo .cctor on thread Thread A

The message Bar retrieves from Foo is “blank”, but Foo was supposed to initialize the message to “Hello From Foo”. The runtime allowed Thread B to reference Foo before Foo’s static constructor completed! It could have just as easily allowed Thread A to reference Bar before Bar’s static constructor completed, but by letting just one of the threads through, a lock became free and we avoid a deadlock. The runtime cannot perform miracles and let both the constructors run to completion.

The morale of the story is: never touch the static member of another type inside of a static constructor.

C++ programmers knew this was a bad scenario, although for slightly different reasons. See the C++ FAQ for the “static initialization order fiasco”. The punishment for C++ programmers who do this is to take a job at a fast food restaurant, but then hard-core C++ devs are pretty heavy handed (the topic for a future post).