September 2003 - Posts
Recently, I've been getting a bit bogged down with my .NET coding. I forever seem to be writing simliar chunks of code all the damn time and cursing VS .NET for not being able to expand little snippets of code into bigger chunks.
When I blogged Scott Hanslemen's awesome developer tools list, my friend Russell Pooley found QuickCode.NET. This code just just that. You tap a little bit of code into the editor, hit a key combination and it expands it for you, replacing placeholders in the script. For example:
I type: prop string MyString Gets or sets the string.
And when I hit Alt+Q, I get:
/// <summary>
/// Private field to support MyString property.
/// </summary>
private string _myString;
/// <summary>
/// Gets or sets the string.
/// </summary>
public string MyString
{
get
{
return _myString;
}
set
{
// check to see if the value has changed...
if(value != _myString)
{
// set the value...
_myString = value;
}
}
}
You can define your own patterns, obviously, and we're evaluating it in anger at one of my clients to get some consistency with our coding standards. A tool like this really makes that easy.
Now, I will say that it's not very sophisticated. In the example above, I would love it if it moved the fields to the top of the class. I'm not a big fan of regions, but that would be one way to do this. When I define my QuickCode .NET template, I could specify that chunk A was supposed to go in region Fields and chunk B was supposed to go in region Public Properties. That would make a big difference.
In fact, when I was writing my last entry on Windows Forms Thread Safety, this tool would be great for defining delegates and the code to flip between the UI.
My girlfriend calls the place where I'm in “pencil sharpening”. It describes a period of time where you're “preparing” to do some work by doing things that don't really need to be done rather than getting stuck in, mainly because I don't really do what I have to do today! Anyway, it's at times like this I usually fire up Reflector and start prodding around in the BCL.
I have a background in Win32 and, as such, I've always known that if you're writing multithreaded UI, it's a very bad idea to manipulate the UI through a worker thread. This can cause all kinds of thread safety issues and, oh god, it's just too horrible to think about - weird hard to find bugs that only happen one in a thousand times, and never with a debugger running. Shudder!
In .NET, if you need to manipulate the UI from a worker thread, you need to use the Invoke method on the form. This handles marshalling the call from the worker thread to the main UI thread. (Which underneath the covers if the thread that's calling down to the GetMessage...DispatchMessage loop that underpins all Windows UI.) This gets around the thread safety problems - your worker thread is suspended while the UI is updated from the thread. Great.
This means you end up with code that looks like this:
private void FudgeStatusBar()
{
if(INeedToCallInvoke)
{
this.Invoke(new FudgeStatusBarDelegate(FudgeStatusBar));
return;
}
// by the time we get here, we're in the main UI thread.
}
So, in order to do my INeedToCallInvoke method, usually in the constructor I capture the thread ID by calling AppDomain.GetCurrentThreadId() and storing it in a private field. INeedToCallInvoke would then check the current ID of the thread, compare it to the field and return true if I was in a different thread.
I've known that you're supposed to use Invoke for a couple of years, but what I have only found out just recently is that there's a property on Control called InvokeRequired. This does the work for you, so what you actually need to do is this:
private void FudgeStatusBar()
{
if(InvokeRequired)
{
this.Invoke(new FudgeStatusBarDelegate(FudgeStatusBar));
return;
}
// by the time we get here, we're in the main UI thread.
}
If you decompile InvokeRequired (using your favourite decompiler) you'll discover this:
public bool get_InvokeRequired()
{
HandleRef ref1;
Control control1;
int num1;
int num2;
int num3;
if (this.IsHandleCreated)
{
ref1..ctor(this, this.Handle);
}
else
{
control1 = this.FindMarshalingControl();
if (!control1.IsHandleCreated)
{
return false;
}
ref1..ctor(control1, control1.Handle);
}
num2 = SafeNativeMethods.GetWindowThreadProcessId(ref1, &(num1));
num3 = SafeNativeMethods.GetCurrentThreadId();
return (num2 != num3);
}
This is obviously a bit more sophisticated than capturing the ID of the thread. I guess that here, until the handle is created, we're just affecting the internal state of the object, hence no message loop, hence no issues with thread safety. Then, at the end, the property is checking to see if the window's thread ID is the same as the current thread ID. When I read this, I remembered about GetWindowThreadProcessId (MSDN)...
/P>Moral of the story - sometimes in .NET, you can understand 99% of how something works, but finding that other 1% can really make the difference!
Wesner Moise has put together a
good blurb on Avalon, which promises to be very interesting and, oh yes, you can learn about it at PDC.
Well, I guess I get to join you all at the wonderous and magical Microsoft Professional Developers Conference 2003!

PS: This has to be the funniest PDC related blog entry I've seen so far...
Joel Spolsky's software company, Fog Creek, has moved offices. Joel had the good fortune and foresight to spend what looks to me like a ton of money on building a really great office for his team. He has posted an article about it called Bionic Office.
Couple of things in the article really drew my attention. First is a quote from Philip Greenspun who posits: “Your business success will depend on the extent to which programmers essentially live at your office. For this to be a common choice, your office had better be nicer than the average programmer's home. There are two ways to achieve this result. One is to hire programmers who live in extremely shabby apartments. The other is to create a nice office.” - and that seriously appealed to me! :-) Although I'm not sure about “developers living at your office” because personally I'm into this XP idea that no one should work more than 40 hours a week unless they really, really have to. (Families may not be as much fun as code but, well, you know...)
He's done a couple of neat tricks that can be done without much capital outlay. Firstly he's put twenty power outlets per desk! Now, this is great. I have a dozen on my desk at home, and they're all full, so I'd say that 20 was about right for a geek! Plus four of his are UPS'd. They're also at desk level, which is good news for me as I'm always grovelling about on the floor trying to steal power points from other people in the office. He's also put an 8 port hub on each desk. This comment tickled me: “I sneer at silly building managers who still think that one LAN port per office is about right. For lawyers, maybe.”
On the serious side, all of his desks are straight and don't appear to have any drawers underneath. I'm not a fan of pair programming, but I am a fan of trying to show someone what's on my screen on look at what's on someone else's screen. For some reason though (and I guess that it's to do with more usable space per physical space), companies tend to use corner desks that are notorious for making it virtually impossible to work side by side with someone.
He's also bought Herman-Miller Aeron chairs, which trust me are the most comfortable chairs known to humanity.
Joel is a lucky, lucky man... although I'm not sure about that green colour.
Brad Abrams, who blogs most excellently about API design stuff posted today about the whole pickle with COM naming conventions and how it impacts .NET, notably the problem that an evolving object model eventually leads to “grafts” being put on the API. For example, imagine that first there was IDispatch, then comes IDispatchEx, then comes IDispatchEx2.
The nub of Brad's question comes from the fact that as he was reviewing some of the Whidbey interfaces, he came across IDataReader2. The question, would we as developers prefer IDataReader2 or IDataReaderFoo, which implies the foo-ness of the extension.
One of the great things that .NET allowed Microsoft to do was more or less start from scratch. CreateWindowEx? ExitWindowsEx? All gone! (There's plenty more, but my Win32 skills have largely fallen by the wayside. Anyway, what's the Ex? Extended? Extension? Extra? One for Raymond Chen...) With .NET, Microsoft got to start again, which means apart from weirdness like everything's supposed to have a strong Pascal name and some things don't (consider XmlDocument, but System.IO - should be System.Io?), everything looks clean and well designed. But, as .NET evolves, what happens - IDataReader2, IDataReader27ExEx, and so on.
I think with Win32, the Ex extension worked because you were just talking about one function - CreateWindowEx is CreateWindow with extra bits. COM gets more tricky. IDispatchEx, however, has tons more features that IDispatch. If you check the MSDN blurb about it, you'll find about a dozen bullets describing just what's so Ex about IDispatchEx. So to me, Ex on an interface is a pain in the butt because I have to remember that if I have an IDispatch, the extra features that I want might be on another interface. So, in COM, I QueryInterface for IDispatchEx in order to get at my objects.
I'll freely admit that types in .NET are going to end up getting extended and enhanced (read “evolved”) over time, but I really must prefer the foo-ness method. I would go so far as to say that IDataReader2 is crazyness - all that's telling me is that it's a later version of the interface! (Of course, so does IDataReaderExExEx, but then we're getting unreadable.)
The idea of implying behavior to an interface makes sense, if we're saying that it's common for a class that implements an interface to support a whole load more behaviour. For IDispatchEx, a lot of those new features seem to be around DISPIDs, so how would IDispatchDispIdBehavior be?
What's not so clear to me is what happens when a method changes, or you want to add an overload to an existing method. Consider an interface like this.
interface IFoo
{
Type FindType(string name);
}
You find that people consuming this interface are always writing code like this:
Type foundType = myFoo.FindType(”Hello.World”);
if(foundType == null)
throw new blahblah...
So, you think to yourself, I'll add an overload, so I want IFoo to look like this:
interface IFoo
{
Type FindType(string name);
Type FindType(string name, bool throwIfNotFound);
}
...the second method here throwing an exception if the type was not found.
Brad's problem (which I suppose is all our problem) here is that you can't change IFoo without it being a breaking change, so you can't do that. But you can do this:
interface IFoo
{
Type FindType(string name);
}
interface IFoo2 : IFoo
{
Type FindType(string name, bool throwIfNotFound);
}
...the developer can check myFoo to see if it is IFoo2 and then call the method with the built in error checking. If not, he/she has to do the checking him/herself.
For the life of me, I can't think of a neat way of doing this. In this case IFoo2 is *better* than the original interface - it really is a 2.0 interface - they've looked at it, and they've made a major change.
One way around this is if the number at the end matched the framework version number. For example e.g. IDataReader2 for .NET 2.0, IDataReader11 for .NET 1.1 (not sure how to separate them without putting 'p' or an evil underscore in the middle - and I guess we'll have thrown away .NET by the time 10.0 rolls around). I'm sure that they could (and will) put the ObsoleteAttribute on the interface, so that if I compile anything against the old version it'll throw a warning.
To me, if foo-ness makes sense, if classes implementing an interface suddenly start all having the same behaviours (like IDispatch-implementing classes tendency to support DISPID queries), then great, lets have IDataReaderFoo. I know that I need foo-ish stuff, so I can query the object for the interface that defines the foo-ish contract.
If foo-ness doesn't make sense because we're just improving the stuff that's already there, then let's hack the version number of the Framework onto the end of the interface name (or even the base class I guess) against the Framework version number.
If I build an app in 2.0 and move to 2.1, the ObsoleteAttribute should be able to tell me that where I've implemented IDataReader2 (the 2.0 version), IDataReader21 (the 2.1 version) is now available and I should use that again. I can then Google for the interface name and hopefully hit some blogs/cool commuity sites/MSDN telling me what new features are in that interface and why I might want to use it. (Some pragma to be able to supress that warning might be nice?)
I know that the naming is ugly, but I really don't want to have to remember in five years time on .NET 3.0 that I'm supposed to be using IDataReader4 and IDataTableExExEx. I want to know just by looking at the name whether it matches the BCL version that I'm using, and I want to be able to find out easily why I should be using, the compiler should tell me that I might have forgotten something, and (haha), I don't want my code to break.
Then again, we could throw away the whole concept of interfaces and work out some replacement that doesn't require this sort of hack. :-)
You know, I remember I time when it was uncommon to find .NET implementations of useful code.
CRC, Cyclic Redundancy Check (and not Class, Responsibility, Collaboration, see XP) is useful for discovering whether changes have been made to a collection of bytes. CRC creates a signature for a collection of bytes, and there's a very low chance that two collections will have the same CRC signature. (This is true for even minor changes to a file.)
The guys at vbAccelerator have a CRC library for .NET, if anyone else out there needs one of these today. Check out the rest of their libraries for more cool bits and pieces.
Lutz Roeder has a
weblog? I never knew that... *Subscribed!*
One of my favourite bloggers, Suzanne Cook, ran an article back in July called Unloading an Assembly. For some of you, it may be a surprise to know that you can only unload an assembly if you unload the entire appdomain that it is loaded into.
This wasn't a surprise to me, but this statement was:
“There's no way to unload an individual assembly without unloading all of the appdomains containing it. This can by done by calling AppDomain.Unload() (or UnloadDomain() on the unmanaged hosting API) for each AppDomain that has it loaded.
“I should point out that this means that, even if your managed Assembly/Module/etc. objects go out of scope, GC may clean the objects up, but the actual file will remain loaded. (That's better, in general, anyway. Loading a file, especially by http, is too expensive to be done over and over, when it can just be cached.)”
Now, call me stupid, but I read this as even if I unload an appdomain, the memory allocated to the file as it's read into the process will not be freed up. This was a particular problem for me yesterday, as we had a situation where we had a server process that over time would generate code for, compile, load and use dynamic assemblies. We didn't want this process eventually collapsing due to a memory leak. I read Suzanne's comment here as that even if I create a new appdomain for the generated assembly, load it and then unload the appdomain, the process would never free up the memory used to store the image of the assembly file, hence the fact that our server process would eventually eat all the memory on the box and die.
We did some tests to see if this was true. Namely we wrote a little app that spat 250 largish assemblies (between 1.5 and 2.5MB) containing random Console.WriteLine statements. We then wrote an application that loaded each one in turn into its own appdomain, created an instance of a type in the assembly and called a known method. If we unloaded the appdomain, memory use (as reported by TaskManager) remained constant. (Around 40MB, I believe). If we did not unload the appdomain, memory crept up towards the 500MB mark, and the whole process slowed down terribly. In my opinion, this shows that the memory allocated to a loaded assembly file is recycled as the process demands more memory to load new assemblies into.
I guess I must have misunderstood what Suzanne was saying... Anyone know what subtlety I've missed in her comments?
Here's an interesting article on The Case Against Extreme Programming.
Personally, I like XP - or rather I like some parts of XP. Some of the criticism in this article rings true with me, however, so I suspect I'm going to have an interesting morning of argu^H^H^H^H interesting discussions.
More Posts
Next page »