August 2003 - Posts
Here it is:
Not sure how I feel about videos. Personally, I just want to dip into the Profiler and play around with it. I think a Web page with some docs is more accessible than a 16 minute video...
NewsIsFree appears to have an RSS feed of the last ten items posted to Microsoft Downloads...
I've run into a couple of weird Windows Forms problems today. In VS .NET 2002, when I used to bring up the call stack on an event handler (”OnWhatever...”), I used to see all of the Framework calls that got me from the last call in my own code to the call I'm actually debugging. Although you can't see the code behind these calls (they're compiled and you have no debug info), they're often useful for getting a hint about what's happening in the Framework assembly by reading the method names.
For example, in the current situation I'm, I've inherited from ListView. I'm overriding OnItemCheck because I want to be told when the user changes the item checks, but I don't want to run the routine that updates the underlying data too often because it involves all sorts of expensive operations. What I've done in my code is set a flag when I think that the check could possibly change - i.e. when I'm programaticlaly setting them when adding them to the list. I check the flag in OnItemCheck and discard any calls that I think are happening in response to me programmatic changes.
However, in between me adding the items to the list and the list being displayed, the OnItemCheck method is being called at some point. That's the reason why hiding non-user code is a problem - I need to ignore OnItemCheck's ideally in all situations when the user is not physically clicking on a check box.
In VS .NET 2003, by default if the call stack contains non-user code (i.e. code running in assemblies that don't have debug info available), the Call Stack window “helpfully” collapses this down to a single line “<Non-user code>”. In effect, this turns what happened between leaving your own code and re-entering your own code is a complete mystery. To solve this problem, right-click on the Call Stack window and check on “Show non-user code”.
With the non-user code visible, I can very quickly see that the OnItemCheck is being called at some point after a call to OnHandleCreated. I can't see what the ListView class is doing (well, I could if I decompiled the thing.), but there is a clue there. Indeed, if I override OnHandleCreated and add set my “ignore” flag before calling the base implemention and clear it afterwards, I get the information I need.
Today's quickie tip comes from the world of Win32 best practice.
In Win32, we were taught to return resources to the state they were before we were using them. This is good OO programming practice generally (makes your operations more encapsulated). My specific example here is the best way to put up an hourglass cursor to the user for a lengthy op.
// save the old cursor...
Cursor oldCursor = this.Cursor;
// put up an hourglass...
this.Cursor = Cursors.WaitCursor;
// do some work...
// restore the old cursor....
this.Cursor = oldCursor;
The idea behind this apporach is that you remove the assumption that the cursor was a default cursor before you got into this method. The bad way of doing this is to explictly set the cursor back to what you think it was before you got into the method. This may not be the case as another method may have changed the cursor before you get your chance to run. In effect, you would have messed up the state of the object and broken the operation of the up-level method.
Moral: always return state back to how it was before you changed it, rather than what you think it was.
After my post yesterday on the C# Coding Standards document, I received a comment from Adam with relation to the performance of the calls. There's a common misconception about how virtual should be used, and I wanted to address the perf issue here. (Comments are here and here.)
Brad Abrams has a superb set of .NET Design Guidelines, which can found on his GDN blog here. He's been kind enough to cut-and-paste sections from internal design documents that the Microsoft dev teams use themselves. One of these (Subclassing Usage Guidelines) speaks about this issue in some detail.
Rather than cut and paste the whole thing, I've edited out some that I think are particularly salient:
Do minimize number and complexity of virtual members in your APIs. Virtual members defeat some performance optimizations the runtime provides and could “box-in” your design.
Do not use virtual members unless you have specifically designed for specialization:
You have a concrete extensibility scenario in mind.
You have written a quality sample demonstrating the extensibility scenario. Preferably the sample should be done by a “3rd party” to independently validate the design.
You have clearly documented contracts of all virtual members.
Do think twice before you virtualize members:
Annotation - The peril. If you ship types with virtual members you are promising to forever abide by subtle and complex observable behaviors and subclass interactions.
I think API designers underestimate their peril. For example, we found that ArrayList item enumeration calls several virtual methods per each MoveNext and Current. Fixing those performance problems could (but probably doesn't) break user-defined implementations of virtual members on the ArrayList class that are dependent upon virtual method call order/frequency.
FxCop Rule (draft): Flag non-sealed public types that introduce virtual members with the message: “Virtual members represent points of specialization in your type. Great care should be taken in exposing virtual members, please see the design guidelines document on this topic and fully consider the ramifications.”
Consider designing classes with inheritance scenarios in mind and appropriate virtual members.
Doing this correctly requires a careful specification outlining the exact contract of all the virtual members. It is strongly suggested that you create at least one subclass ideally in the shipping product. Although this is the ideal, it is somewhat costly.
A colleague of mine directed me to this C# coding standards document.(PDF document) on idesign.net.
It's pretty good. I'd say I agreed with about 99% of the things in there. One to be wary of is the author's desire to make every member virtual, which is bad for perf, and also doesn't make common sense to me with regards to having a “locked down” class that you open up more over time.
Had reason to spend some time with Scott's .Text yesterday.
It really is *rather good*. As Jason Alexander points out, there's plenty of ASP.NET best practice in there that's worth checking out, even if you don't actually need a blog right now.
One of the most interesting features for me was driving the functionality on weblogs.asp.net where separate folders (weblogs.asp.net/mreynolds/, weblogs.asp.net/rpooley) drive exactly the same code base but effectively creates partitions to the same SQL database. (i.e. all blogs are held in the same SQL database, but the folder effectively indicates a partition - i.e. the code is able to determine that anything requeest that appear to come from pages in the folder mreynolds belongs to blog 27, whereas anything in rpooley belongs to blog 28.) What he's effectively got going on is an arrangement where he can appear to create entirely separate Web sites with its own, separate, secure set of data simply by writing a single row into a single table. Now that's good thinking and good design.
I must say though Scott... Open Source? You could make a fortune, dude!
Bit of a simple one this, but I didn't know about it.
One of my favourite .NET tricks is using ArrayList.ToArray(Type objectType). For those who don't know, this creates a strong array of objects for a given type. So, if I chuck a load of objects into an ArrayList (say I'm doing some processing) and I want to pass the contents to some other method as an array, I use the ToArray(Type objectType) to get a strongly-types array, rather than a weak object array.
The helper function that ToArray(Type objectType) is using under the hood is Array.CreateInstance. This version of CreateInstance (as opposed to System.Object.CreateInstance) returns a strong array of a given type and of a give size. Pretty helpful.
Not really about .NET, but I use this for work... :-)
I have to drop my notebook and tablet into several different networks during the week. It's a pain that I have to reconfigure network and proxy settings everytime I do this. (Particuarly, one client of mine doesn't use DHCP, otherwise this would be a bit of a non issue.)
The NETSH command can be used from batch files to change network settings. Here's how to change an interface to use DHCP:
netsh interface ip set address "Local Area Connection 2" dhcp
netsh interface ip set dns "Local Area Connection 2" dhcp
And here's how to switch it to a fixed IP...
netsh interface ip set address "Local Area Connection 2" static 192.168.144.59 255.255.255.0 192.168.144.4 1
netsh interface ip set dns "Local Area Connection 2" static 192.168.144.2
Here's a .reg file for setting the proxy:
Windows Registry Editor Version 5.00
...and for clearing the proxy
Now, if only SharpReader would pick up the proxy settings from IE automatically. ;-)
has a thing or two to say about what's happening with SourceSafe going forward
Quote: But for VSS, the Roadmap is HUGE! The Roadmap is 100 decibels of source-controlled joy. Finally! The SourceSafe feature team is planning to do more than fix bugs. As many customers have observed recently, the last few VSS releases have seemed like a reverse alphabetical countdown to something: 6.0, 6.0a, 6.0b, 6.0c, 6.0d. Whidbey will be different...
More Posts « Previous page
- Next page »