July 2005 - Posts
I recently needed to reinstall the Java Runtime environment on my desktop in order to view sites with Java Applets. When I went to Sun's download site, I got the familiar Windows XP information bar saying that the site was attempting to install an ActiveX control and the download wouldn't proceed without it.
I find it rather amusing that I would need to install an ActiveX control in order to download the runtime environment who's most common use is to avoid the need for ActiveX controls. But maybe that's just me.
While I didn't quite resort to chocolate bribery, I just received word that I have been accepted into the Longhorn Beta 1 program. I've got a laptop sitting right here (otherwise collecting dust) just waiting to take it for a test drive. I'd love to say that you should check back for screen shots, news, etc. but I have no intention of violating any of my various NDAs. But rest assured the minute the details are publicly available, I'll do a brain dump of what I've learned.
I got an email this evening from alert reader Teddy Garcia telling me there was a bug in the 2.0 version of the StudentCollection class that shipped with my MSDN article. My first instinct was that he had to be mistaken because I of course am above simple coding errors. :-) But sadly he was not mistaken and I am in fact fallable.
The problem is in the ResetList method. This method clears out the current list of items and replaces it with the newly sorted list. However, in the source code I was clearing the list by calling Me.Items.Clear(). While that would seem like the correct thing to do, this will cause an IndexOutOfRangeException when the DataGridView tries to display the sorted list. The reason is that the DataGridView never received notification that the original records were removed from the list, but when I call the Add() method the DataGridView does receive notification of the new rows being added. This in turn causes the DataGridView to think there are more rows in the collection than there really are and hence the IndexOutOfRangeException.
The solution to this is to call the BindingList(Of T).ClearItems() method instead of BindingList(Of T).Items.Clear(). This method calls the internal list's Clear method and then raises the ListChanged event which is what the DataGridView needs to keep everything in sync.
I did a little bit more research and found that the BindingList(Of T) class has several methods implemented to ensure that the ListChanged event gets fired when the internal list changes including InsertItem, RemoveItem, and ResetItem. This got me curious though as to why there was no AddItem. So through the miracle that is Lutz Roeder's Reflector Tool, I looked at the IL for the BindingList(Of T) class and saw that it's base class (Collection(Of T)) implements the Add method by finding the last element in the list and then calling the virtual InsertItem method which for the BindingList(Of T) also fires the ListChangedEvent. Ah, the joys of object oriented programming.
I have updated the source code to include this fix. Much thanks to Teddy for sniffing this out for me. You can download the file (ZIP) here.
I wasn't always the .NET fanatic that I am today. In fact, before learning about .NET I spent a few years in the Unix/Java/Netscape world working on websites that are still in production today. But before that even, I spent the first 10 years of my career working in OS/2.
I started out working as a contract programmer for Kodak writing xBase programs using tools like FoxPro and dBase III Plus in DOS. Ah, those were the days. When EGA screens were everywhere and my heart thumped at the site of my brand new IBM PS/2 Model 70 A/21. A screaming Intel processor running as much as 21 Mhz! I believe it had the full loudout on memory, a whopping 1 Megabyte (only 640K of it usable by DOS). Shortly after joining on at Kodak though I would get the opportunity that would launch my fledgling programming career when I was sent to training on a brand new language for developing a new type of application called a Graphical User Interrface. The language was called Easel and the compiler alone cost $26,000. It was a very verbose language with syntax similar to this (if memory serves):
visible enabled red graphical region Fred
size 100 100
position 10 10
It had all sorts of other fun syntax like "touchability of" which equates to enabled in modern languages or "resumable block" for creating subprocesses. After working with the language for about a year or so I got the opportunity of a lifetime, and went to work for Interactive Images, the company that made Easel as a developer on their commercial GUI interface to the IBM Profs email system. I was 23 years old then and I absolutely loved my job, my coworkers, and the technology. I couldn't believe I got to do what I did and got paid for it (although not much).
That was when I first saw OS/2 in it's early stages with release 1.1. About this time is also when Windows 1.0 came out but nobody took it too seriously, after all it wasn't business oriented. :-) Well, during those years of working with Easel both for Easel Corporation (formerly Interactive Images) and then when I struck out on my own as a consultant I got to see OS/2 evolve into the premier preemptive multi-tasking platform for PCs. OS/2 however was too far ahead of its time which turned out to be its undoing. The memory requirements for OS/2 were huge at the time (laughable now) requiring as much as 8 Megs. Back then memory was a huge constraint on PCs and so only businesses could afford the investment in 8 Megs. Windows on the other hand had much smaller requirements and as people started buying PCs for home use, Windows spread like wildfire.
I stopped using OS/2 when the Internet caught on but many of my old clients went on to do new development with Easel and OS/2 well into the 2000s. When I asked one client why they still use OS/2 they said "Because OS/2 doesn't get viruses!" In fact, OS/2 is still rock solid as an operating system on the computers it was meant to run on. But time marches on and so IBM has pounded down the last coffin nail for OS/2. With that I not only say goodbye to an operating system, but the horse I rode in on.
Former Easel-ites of Note
There have been several former Easel employees who have gone on to work with other companies and do some pretty great things. Here is a list of the ones I know of and their titles back when I knew them. If you are reading this and you too once worked for Easel, drop me a comment and I'll add your name and info.
R. Douglas Kahn, President
John McDonough, VP of Finance
Steve Sayre, VP of Marketing
Bob Gleason, VP of Sales
Tom Bilotta, VP of Development
Dave Panos, Easel Product Manager
Diane Hall, Development Mgr (my ex-Boss and a very cool lady)
Katina Engle (Node 1 of my 3 Node Umbilical System)
Doug Gibson (Node 2 of my 3 Node Umbilical System)
Mike Diehl had a recent blog post about debugging Windows Services. As I've been doing quite a bit of this lately, I thought I might jump in with some more information on Windows Services and the fun that is debugging them.
Debugging Service Startup
When a Windows Service is installed into the Service Control Manager, it doesn't start running until it's either started manually or if the installer StartType property is set to "Automatic" then after the system reboots. What this means to your debugging is that you can't simply install the service and attach the Visual Studio debugger to the process as there isn't one to attach to until after you start the service. However, once you start the service if you have a bug such as an exception in the service's initialization you won't get the debugger attached to the process before it's too late. So then, how do you debug the service class' initalization? Using the System.Diagnostics.Debugger.Lauch() method. // The main entry point for the process static void Main()
This method pops up the following screen asking you which instance of the debugger it should use to debug the application.
Note that I have placed the Debugger.Launch method call inside a "#if DEBUG" compiler directive. DEBUG is a predefined directive that is automatically added when the application is compiled in Debug mode. Therefore, while I am working on the application the Debugger.Launch method will be called, but when I switch to Release mode the C# compiler will skip that command. This will keep you from having to remember to remove all of your Debug code (not that you shouldn't be doing that anyway).
Debugging After Startup
After the service has intialized and the OnStart override has been executed the service will begin its work. If you've used the method listed above to start the Debugger when the service starts up you can then create breakpoints in Visual Studio or you can put Debugger.Break() methods into your code where you want the debugger to stop code execution.
You can however choose to debug a service that is already running, by attaching the Visual Studio Debugger to the process. Click on the Debug menu option and select "Processes". This will bring up the following window listing the processes currently running on the machine.
Select the process you want to debug and hit the 'Attach..." button. The next window asks what types of programs you want to debug. Make sure the "Common Language Runtime" option is checked and hit OK. You are now debugging that process. If the EXE is compiled in Debug mode and the PDB file is in the same directory as the EXE, you should see the source code for your service. Just set your breakpoints and you're off and debugging.
Recompiling The Service
When the Service Control Manager tells the service to stop, the process for the service should finish up any work and end gracefully. As long as this is happening and no threads are left running, you should be able to simply recompile your service in place without reinstalling it. However, if you do leave any residue running Visual Studio will give a build error saying that the EXE file cannot be copied because access is denied, file in use by another process. This is a design issue so if you find that after stopping your service you still cannot access the EXE file, you should debug the application to make sure you have cleaned up all of the resources and threads.
I tested every version of the Account property settings and no setting would prevent me from debugging the application. Therefore, you should not need to add any users or groups to the "Debugger Users" group on your machine. My testing on this was pretty quick though and so there could be some instances where this might be required.
Hope this information helps in your Windows Service Debugging
I have had the honor of working with the Patterns & Practices Team on a set of design patterns around providing secure service communications. My involvement has been somewhere between casual observer and boat anchor but it has been great watching these patterns and documents evolve. Now the workspace on GotDotNet is open to the public so anybody can download, review, and comment on the patterns and guidance they provide. If you interested in learning more about implementing security with web services, WSE, and x.509 this is a great resource. The documents are also available as a CHM file.
Congrats to Tom Hollander and the rest of the team on a job very well done. Visit Service Orientation Patterns on Patterns.GotDotNet.com.
The Dallas Morning News recently featured an article showcasing the rising demand for qualified .NET developers.
"We've seen continuing demand for the past two years," said Kimberly Bowden, recruiting manager for the Impact Innovations Group in Dallas. Typically, about 15 percent to 20 percent of the positions the firm is working to place are for developers with .NET skills.
In the article it talks about how only two to three years of .NET experience are required to be considered a Sr. Developer with such a new technology.
"Typically, two to three years' experience would be considered a junior skill set for a programmer, but with .NET, that's going to be your tenured folks," said John Reed, regional vice president in Dallas for staffing firm Robert Half Technology.
And who's happy face should grace the article in the paper? Dallas .NET User Group Leader and Notion Solutions trainer Dave McKinstry. Way to represent Dave!
I heard a funny story a few years ago from a .NET developer recently back from India. Apparently his prospects for finding a wife were improved by learning .NET because after the DotCom bubble burst, parents heard about all of the Java programmers out of work and so Java developers became less desirable as potential son-in-laws! :-)
In my very first blog post, I
whined discussed the troubles I had installing Visual Studio 2005 Beta 2 on my fancy-shmancy new Media Center PC. After a lot of searching I happened across Aaron Stebner's Weblog in which he was discussing deployment issues around the .NET Framework and MCE. I posted a comment asking him if he knew when the compatibility issue would be fixed and not only did he answer my question via this post, he even created a set of configuration files for download that allow .NET 2.0 and Media Center extensions to peacefully coexist. I download the files, reinstalled VS 2005 Beta 2 and all is well.
Thanks Aaron, this was a huge help and I can now discard my pesky VPC image and get down to some serious exploration.
If you have visited www.Rochester-Consulting.com you probably have noticed that it's currently requiring authorization. We're in the process of rolling out a brand new website based on SharePoint 2003 and so we have access to it locked down while we are working on it.
Along with information about the company I'm also going to be putting up sample code, articles, resources and other content that .NET developers might find useful. I'm also hoping to have a discussion forum for people to talk about any of the content they see.
The site will be live in a couple of weeks, so please pardon our dust and check back soon!
The article I wrote for MSDN magazine has started to show up in subscriber mailboxes. It describes creating custom collections that implement design-time databinding support both for .NET 1.1 and for .NET 2.0. Here's a quote from the article.
To enable your collection to have design-time data binding, you next need to implement the IBindingList interface. The IBinding- List interface defines the methods and properties necessary for a list-based UI control like the DataGrid to be able to add and remove items from the list, sort the list based on the selected column, and search for a value in the list. Figure 4 shows the complete list of properties and methods that define the IBindingList interface.
The source code is downloadable for both versions at http://msdn.microsoft.com/msdnmag/issues/05/08 (Available Tuesday, July 12) and if you have any questions feel free to ask them here or send me an email at Paul<at>Rochester-Consulting.com.