jump to navigation

Hey, Watch this! October 28, 2009

Posted by markegilbert in Visual Studio/.NET.
add a comment

I’m sure I am the second-to-last person* to realize this about the Visual Studio Watch window, but not only can you have it monitor public properties of an object, it can monitor private ones as well.

WatchWindow

I think the barrier to me realizing that it could see the values for the public methods is that over half the time I’m relying on IntelliSense to drop something in.  IntelliSense, of course, will only show the public properties of an object, or in the very least it won’t show private ones.  The other day, I tried pasting in something like MyObject._MyPrivateVariable, and sure enough it worked.  I didn’t realize what I had done until a few seconds after I hit Ctrl-V.  When I had, I deleted it and manually typed the full variable reference out, just to confirm what I had done.  Sure enough, IntelliSense stopped providing any information once I had "MyObject._" entered, but completing the private member name worked.  The current value appeared immediately, and updated as the execution progressed.

This really shouldn’t have come as a surprise to me.  Had I put a watch on just "MyObject" and then expanded the + sign next to it, the private members would have shown up then.  These values also appear in the QuickWatch (available when you right-click on an object in code while you are in Debug mode) as well as in the Command Window.

It’s really cool when I get lucky and stumble onto something like this.  Then again, even a stopped watch is right twice a day.

 

* The last person will be my 9-month-old daughter when she starts programming next month.

Unit testing with DBNull October 13, 2009

Posted by markegilbert in Agile, Visual Studio/.NET.
add a comment

Recently, I was writing a class that would parse a DataRow (returned by a stored procedure) and construct a strongly-typed object from it.  I wanted to test the case where the stored procedure returned DBNull for one of the fields.  My first attempt at the unit test setup started out like this:

Dim DPTable As DataTable
Dim DataRowValues() As Object = {Value1, Value2, Value3, System.DBNull.Value, Value4}

DPTable = New DataTable
DPTable.Columns.Add(New DataColumn(“Col1Name”, GetType(Long))
DPTable.Columns.Add(New DataColumn(“Col2Name”, GetType(String))
DPTable.Columns.Add(New DataColumn(“Col3Name”, GetType(Long))
DPTable.Columns.Add(New DataColumn(“Col4Name”, GetType(String))
DPTable.Columns.Add(New DataColumn(“Col5Name”, GetType(String))

DPTable.Rows.Add(DataRowValues)
MyTestObject = New MyClass(DPTable.Rows(0))

Mock up a table and add a test row to it.  Simple.  The problem was the compiler complained about trying to directly assign System.DBNull.Value in the Object() array: "Value of type ‘System.DBNull’ cannot be converted to ‘String’." 

Ok, so DBNull isn’t a value you can assign to a .NET object. What you CAN do, however, is use a valid value in the Object() array and then assign DBNull to that cell in the DataRow, but after you’ve added it to the DataTable:

Dim DataRowValues() As Object = {Value1, Value2, Value3, SomeValidValue, Value4}

DPTable.Rows.Add(DataRowValues)
DPTable.Rows(0).Item(“Col4Name”) = System.DBNull.Value
MyTestObject = New MyClass(DPTable.Rows(0))

That worked like a charm.

Cassini Web Server Silliness October 9, 2009

Posted by markegilbert in Visual Studio/.NET.
add a comment

Recently I glanced down at my system tray to see this:

Server Craziness

Yes, you’re actually seeing no less than six instances of the Cassini web server running on my machine (and yes, I do keep the Windows Task Bar on the left side of my screen).  Visual Studio fires up one instance for every web application in a solution, so when you put it into debug mode, they all start up.  It’s common for me to have more than one web app in a VS solution – main web site, admin tools, web service, web service test rig, etc. – but I definitely set a new personal record with this one.

The Silver "Bulletsh" of Questions October 2, 2009

Posted by markegilbert in General.
add a comment

One of my favorite movies is “The Hunt for Red October” with Alec Baldwin and Sean Connery.  I’ve lost count of the number of times I’ve seen it, but it I’m fairly sure I’ve cleared 25 by now.  Once you’ve seen it, how can you resist quoting the line “Most things in here don’t react too well to bullets”, making sure to add the “sh” sound at the end?

There are several great scenes in the movie, but one of my favorites is where Jack Ryan (Baldwin) is trying to come up with a way to basically steal a state-of-the-art Soviet submarine, avoid the need to eliminate the entire crew, and convince the Soviet government that the United States doesn’t have it.  Ryan is convinced that the captain of the submarine, Marko Ramius (Connery), is trying to defect and wants to deliver the submarine to the United States.

The scene starts off with Ryan realizing that he doesn’t need to figure out to get the crew off and dupe the Soviet government – Ramius must have already figured out how to do that.  So, he reasons, I just need to figure out what Ramius is going to do.  Ryan continues his verbal brainstorming with “They’d have to want to get off.  How do you get a crew to want to get off a submarine?  How do you get a crew to want to get off a nuclear…”  At that point, he has his answer.  “How do you get a crew to want to get off a nuclear submarine?”  Easy – fake a reactor accident.  What I love about this scene is Ryan continuing to rephrase the question until he comes up with one that he can answer.  Once he got around to including “nuclear” in his question, the answer became obvious.

This skill is increasingly useful in the “information age”, where search engines are the true portals to the Internet.  Imagine trying to find anything on the Net without using something like Google or Bing – inefficient, at best.  As good as search engines have become, though, the answers they can lead us to are usually only as good as the queries we start with. 

In several cases, it’s easy to know what to search with.  Suppose you’re presented with an error message like “Derived classes cannot raise base class events.”  If you want to find a way to correct or avoid that problem, the most logical first search should be on the message itself (in which case you might turn up this light and fluffy post).

In other cases, though, the question is harder to formulate.  Suppose you don’t know that you can have one class inherit from another class, but you want several to share some of the same functionality.  It will probably take you a few tries (at least) to arrive at the silver bullet question – the one that you will be able to find an answer for.  It’s times like this where Ryan’s skill comes into play.

When I’m faced with a situation like this, I try to formulate the best question I can and see what comes up.  I don’t really expect to find the answer with my first search, but rather, I’ll skim through the first couple of pages of hits looking for alternate keywords and phrases to try, and then try another search.  Wash-rinse-repeat until I have my answer.

Now, I don’t want to mislead you into thinking that this technique always works, or that I can always apply this technique with success.  There are times when I just can’t find what I’m looking for – I can’t formulate that silver bullet question. 

As I was formulating my notes for this post, I began to wonder if there are classes or seminars out there to show you how to ask better questions, or show you ways to reformulate your current question into one that you can find an answer to.  One technique might be the “Ryan Approach”.

Another might be to completely explain the issue to someone who isn’t involved.  I can’t tell you how many times I’ve asked a colleague to come over to my desk and look at the problem.  They stand there for two to three minutes while I explain what’s happening and what I’ve tried.  The act of having to verbalize everything about the issue to other person will more times than not lead me to the answer – and the other person doesn’t have to do or say anything.  They just stood there and listened.

What other tricks or techniques can help you to formulate the silver bullet of questions?

Raising base class events September 28, 2009

Posted by markegilbert in Visual Studio/.NET.
1 comment so far

On one of the forms of my side project, I grouped like controls into a series of custom user controls.  Those user controls all shared a bit of functionality, so I decided to create a user control base class that all of the others inherited from.  All of the common functionality lives in the base class where all of the deriving controls can use it.

One piece of that common functionality was an event called MessageGenerated.  Something would happen in one of the user controls that would generate a message that the user needed to see.  The main form (which contains all of these user controls) has an area where messages are displayed, so I wanted the user controls to raise the event and the main form to handle it.  Seems simple enough.

I put the MessageGenerated declaration in the base class:

Public Event MessageGenerated(ByVal sender As Object, ByVal e As MessageEventArgs)

And then I tried raising the event from one of my user controls:

RaiseEvent MyBase.MessageGenerated(NewSender, New MyBase.MessageEventArgs(NewMessage))

That unfortunately resulted in a compile error:

Derived classes cannot raise base class events.

Yay.  I found another specifically-disallowed feature of .NET.  Yay.

After a bit of research, I came across this article that described why this was not allowed and how to get around it: http://msdn.microsoft.com/en-us/library/hy3sefw3(VS.80).aspx.  The key sentence is here:

When you create a class that can be used as a base class for other classes, you must account for the fact that events are a special type of delegate that can only be invoked from within the class that declared them.

So, the solution (as this article describes) is to provide a Protected method in the base class that wraps RaiseEvent, which allows the derived classes to invoke the event indirectly.  In particular, the methods needs to be “protected virtual void” in C#-ese, or “Protected Overridable Sub” in VB-ese:

Protected Overridable Sub OnMessageGenerated(ByVal NewSender As Object, ByVal NewMessage As String)
    RaiseEvent MessageGenerated(NewSender, New MessageEventArgs(NewMessage))
End Sub

My derived classes can then call MyBase.OnMessageGenerated in place of RaiseEvent.  The main form, then, handles this base class event for each of the controls, allowing me to address each control differently if I needed to:

AddHandler Me.BookFieldGeneralControl.MessageGenerated, AddressOf Me.MessageGeneratedHandler

AddHandler Me.BookFieldNotesCategoriesControl.MessageGenerated, AddressOf Me.MessageGeneratedHandler

AddHandler Me.BookFieldImagesControl.MessageGenerated, AddressOf Me.MessageGeneratedHandler

CEO: Chief Exec() Oddity September 23, 2009

Posted by markegilbert in SQL Server.
add a comment

I have a side project that I’m working on building a desktop application based running on SQL Server Express, and ran into an interesting issue with T-SQL.

The Setup
Since I’m distributing this to users who are geographically distant from me, and because those users are firmly in the “poweruser” category – not programmers – I needed to provide an easy way for them to get their local copies of SQL Server Express updated when I modified the table structure.  I decided to build a bootstrapper class that runs through a series of SQL Scripts – each one with its own version number attached – until the local database was up to date.  The local database contains a table that stores the current version of the database (which is designed to match the application version), and it will only apply the scripts that need to be applied, and in the order that they need to be applied.

The Issue
The most recent database modification I needed to make was to add a new column to a database and then populate that column with the ID of that row.  It would have been handy in this case if SQL Server allowed me to define the Default value for a column as the ID column, but it specifically disallows that:

Msg 128, Level 15, State 1, Line 1
The name “id” is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables. Column names are not permitted.

Ok, so Plan B.  Use an ALTER statement to add the new column, and then an UPDATE statement to populate it:

ALTER TABLE MyTable ADD MyNewCol [int] NOT NULL DEFAULT 0;
UPDATE MyTable SET MyNewCol=ID;

Simple, right?  Unfortunately, this pair throws an error:

Msg 207, Level 16, State 1, Line 0
Invalid column name ‘MyNewCol’.

Even when I tried to run this in SQL Server Management Studio (SSMS), it fails with this same error.  I think what was happening is that the ALTER statement didn’t completely commit to the database in time for the UPDATE statement to run.  If I ran these two separately in SSMS (highlight first statement, CTRL-E, highlight second statement, CTRL-E) it worked fine, but I wouldn’t have that option in script.  The statements would have to run back to back, and I would need to find a way to make them play well with each other.

The Solution
I did some digging on the interweb and came across this post: http://www.sqlservercentral.com/Forums/Topic255804-8-1.aspx#bm256576.  The solution was to wrap both statements in an EXEC() function call – basically treating them as dynamic SQL:

EXEC(‘ALTER TABLE MyTable ADD MyNewCol [int] NOT NULL DEFAULT 0′);
EXEC(‘UPDATE MyTable SET MyNewCol=ID’);

This worked.

Asking for Trouble
Then I got gutsy.  There isn’t anything after the UPDATE statement that depends on the value of MyNewCol – why would I need the EXEC call around that statement too?  This pair of statements should work just as well, right?

EXEC(‘ALTER TABLE MyTable ADD MyNewCol [int] NOT NULL DEFAULT 0′);
UPDATE MyTable SET MyNewCol=ID;

Yeah – gutsy really wasn’t working for me today.  As it turns out, this also fails with the “Invalid column name” error.  As a result, I went with the dual-EXEC() calls.

It’s puzzling why the UPDATE needed to be invoked via EXEC() too, and unfortunately I don’t have a good explanation for that.  At least I have a method that reliably adds and populates my column, so that will have to be good enough for now.

Pigeon faster than the interwebs September 11, 2009

Posted by markegilbert in General.
add a comment

I wonder how the pigeon’s speed would stack up against an unladen African Swallow: http://ca.news.yahoo.com/s/reuters/090909/odds/odd_us_safrica_pigeon

Subversion stepping on its own toes September 10, 2009

Posted by markegilbert in Agile.
add a comment

Last week I hit an interesting issue with one of the projects running under our CruiseControl.NET build server. Before I get into the specific, I need to lay out some of the structure.

 

“He’s hitting me!”

Nearly all of the public-facing sites that my company builds have some element of Flash to them. The Flash source code and especially all of the assets that get rolled in to a finished SWF take up quite a bit of room on the hard drive.

We learned pretty early on that pulling all of the Flash source code down to the build server was a waste of time because 1) we had limited space on the hard drive and the Flash assets took up a LOT of room; and 2) NAnt wouldn’t do anything with it – the Flash team was already compiling the SWFs for us and committing them to Subversion. All we were doing was copying them (via NAnt) from the folder that the Flash developers were using and put them in the /swf folder below the site web root. So, we switched from using a single <sourceControl type=”svn” /> block to using <sourceControl type=”multi” /> (http://confluence.public.thoughtworks.org/display/CCNET/Multi+Source+Control+Block), and cherry-picking which folders in Subversion we would pull from.

1

A couple of weeks ago, one of my colleagues, Joel, suggested that we could have CCNet pull the compiled SWFs down from Subversion, and drop them directly into the /swf folder below the site root on the build server. That would save a step in NAnt, would allow the overall process to run slightly faster (by not copying the SWFs), and would help to conserve room on the hard drive (by not storing two copies of the SWFs).

2

I thought that was a good idea, and I retrofitted one of my projects to use that new process. It seemed to work great.

 

“No, me first!”

Now, as many of you know, we come to the point of the blog post where the author reveals “TheCatch”.

When I tried to use the same modified on a completely fresh project – one where none of the directory structure on the build server existed yet – CCNet through this error: “Failed to add directory ‘wwwroot’: object of the same name already exists”.

My first thought was a case-sensitivity clash. Subversion is case sensitive but Windows is not, so it’s possible to have two folders in the former such as “mybranch” and “MyBranch”, but my Subversion client will have fits when it tries to being those down to the latter. After checking the repository and the working folders on the build server, everything matched just fine. When I stopped and thought about it some more, I realized this probably couldn’t have been the cause since the build script for the new project was nearly a direct copy of one for a previous project – a previous project that had been running smoothly for weeks.

 

“Do I have to split you two up?”

I decided to fall back on a tried-and-true method of troubleshooting – comment out successive chunks of code until the error goes away. I had two <svn> blocks in the CCNet.config file, the first for populating the MyBranch/site/wwwroot working folder, and the second for populating the MyBranch/site/wwwroot/swf working folder. I removed the latter and re-ran the project. Lo and behold, it worked! I then replaced the second <svn> block and ran it again, fully expecting it to fail again. Shenanigans – it STILL worked! I blew away everything under the MyBranch in the working folder on the Build Server, and made sure I could reproduce this. Sure enough I could.

I began to suspect that the source of the problem was that I had one working folder being placed inside another. Up to this point, I had been assuming that the <svn> blocks were executed sequentially, and in the order that I placed them in the ccnet.config file. Perhaps they were being processed in reverse order. If that was the case, then the Flash source would get pulled down first, and the Subversion working folder of “swf” would get created in a “regular” folder structure of MyBranch/site/wwwroot. Then, the first <svn> block gets processed, and that tries to create a Subversion working folder for MyBranch/site/wwwroot. Since that folder already exists as a regular folder, it chokes.

When I removed the second block, the “wwwroot” folder was able to be established as a working folder. Then when I added the second block back in with “wwwroot” already there, it didn’t have a problem with adding another working folder as a subfolder.

I haven’t been able to find a way to force a specific execution order on the <svn> blocks. It may be that they get executed in reverse order every time, or that they get executed deepest-level-first, or that it’s not deterministic at all. At any rate, the hack that I settled on was running the project through once with just the first <svn> block to establish “wwwroot” as a working folder, and then adding the second block to get the rest. This is only an issue when the build project is first being configured, so I don’t feel overly terrible about handling it this way.

My buffer runneth over September 7, 2009

Posted by markegilbert in Tools and Toys, Visual Studio/.NET.
add a comment

In the new release of NAntRunner, one of the new features is a checkbox to add the -verbose switch to the NAnt call. In the course of testing it, I found that NAnt would hang when I ran a non-trivial build and deploy script. When NAnt.exe hung, it locked up NAntRunner, too. If I ran that same script from the command line using NAnt (bypassing NAntRunner), it completed fine.

Through some tinkering I found that once NAnt.exe hung, I could kill it off using Task Manager and then NAntRunner would give me control back. I started doing some searching for “process.start hung” and “process.start doesn’t exit”, and eventually came to a couple of articles that talked about the output buffers filling up:

http://www.velocityreviews.com/forums/t123227-console-application-hangs-when-called-from-processstart.html

http://stackoverflow.com/questions/439617/hanging-process-when-run-with-net-process-start-whats-wrong

Both of these discuss redirecting the buffers for a spawned process. As it turns out, the buffers have a 2K limit and if they fill up, the process hangs. That sounded awfully familiar.

All versions of NAntRunner have redirected the standard output and error buffers for the spawned process so I could display the contents of those buffers in the NAntRunner interface. Before 0.4, I would wait until the process finished and then get the entire contents of the buffer:

Class NAntProcess
    …
    Public ReadOnly Property StandardError() As String
        Get
            Return Me._SystemProcess.StandardOutput.ReadToEnd
        End Get
    End Property

    Public ReadOnly Property StandardError() As String
        Get
            Return Me._SystemProcess.StandardOutput.ReadToEnd
        End Get
    End Property
    …
End Class

When I started using the verbose switch, the NAnt process hung because the process generated much more output than before (imagine that, “verbose” equals “more”), and the output buffers filled up before the process finished. So, I had to change how I was grabbing the output messages off.

The VelocityReviews.com link above mentions BeginOutputReadLine, so I did some more digging and came up with this MDSN article which shows how to pull these messages off asynchronously:

http://msdn.microsoft.com/en-us/library/system.diagnostics.process.beginoutputreadline.aspx

This involved handling the OutputDataReceived and ErrorDataReceived handlers for the process, and then appending the messages as they were generated using a pair of StringBuilder objects. The modifications looked like the following (only the relevant portions of the NAntProcess class are shown):

Class NAntProcess
    Private _StandardOutputBuilder As StringBuilder
    Private _ErrorOutputBuilder As StringBuilder
    Public Sub New(ByVal NAntExecutablePath As String, _
                   ByVal NewScriptToRun As String, _
                   ByVal NewTargetFramework As String, _
                   ByVal NewBuildTarget As String, _
                   ByVal ShouldEnableVerboseMessages As String, _
                   ByVal NewOtherArgs As String)
        …

        ‘ Configure the asynchronous output collection
        Me._StandardOutputBuilder = New StringBuilder
        Me._StandardOutputBuilder.AppendLine(Me._NAntExecutable & ” “ & Me.GetArgumentsForNAnt)
        Me._StandardOutputBuilder.AppendLine()
        Me._StandardOutputBuilder.AppendLine()
        Me._ErrorOutputBuilder = New StringBuilder
        AddHandler Me._SystemProcess.OutputDataReceived, AddressOf Me.StandardOutputHandler
        AddHandler Me._SystemProcess.ErrorDataReceived, AddressOf Me.ErrorOutputHandler
    End Sub

    Private Sub StandardOutputHandler(ByVal sendingProcess As Object, ByVal outLine As DataReceivedEventArgs)
        If Not String.IsNullOrEmpty(outLine.Data) Then
            Me._StandardOutputBuilder.AppendLine(outLine.Data)
        End If
    End Sub

    Private Sub ErrorOutputHandler(ByVal sendingProcess As Object, ByVal outLine As DataReceivedEventArgs)
        If Not String.IsNullOrEmpty(outLine.Data) Then
            Me._ErrorOutputBuilder.AppendLine(outLine.Data)
        End If
    End Sub

    Public ReadOnly Property StandardOutput() As String
        Get
            Return Me._StandardOutputBuilder.ToString
        End Get
    End Property

    Public ReadOnly Property StandardError() As String
        Get
            Return Me._ErrorOutputBuilder.ToString
        End Get
    End Property
End Class

After I got this implemented, I realized that I wouldn’t need the verbose switch to cause this problem. In theory, the “regular” output from a very involved NAnt script could cause the buffers to fill up. It’s just a fluke that I hadn’t hit this up to this point.

NAntRunner 0.4 Released September 4, 2009

Posted by markegilbert in Tools and Toys.
add a comment

Meet the new kid

I just released NAntRunner 0.4, now available at http://CodePlex.com/NAntRunner. Upgrading to the new version is easy. Simply download the 0.4 ZIP, and extract it to the folder with your previous installation of NAntRunner (your existing settings will be preserved). There were three main things I wanted to tackle in this release. I ended up doing four.

First, I replaced the treeview controls with a user control that rolls everything up. This user control actually started out life in another one of my tools – IISTweak – and I had always intended to incorporate it into NAntRunner. When I did that I realized I had some more work to do to get it closer to being generic. I don’t think the control is completely baked yet, but it’s definitely closer.

For those of you who download the source code and want to tinker, I found an interesting quirk with Visual Studio 2008 and this update. The new user control is called NavigationTree, and it is part of the NAntRunner assembly (the executable). If you do anything with the control in the designer mode on the Main form, Studio updates the instantiation of this control in Main.Designer.vb file to read as follows:

Me.MainNavigationTree = New NAntRunner.NavigationTree

That, however, causes a compile-time error. If you remove the “NAntRunner” assembly reference so it reads as follows:

Me.MainNavigationTree = New NavigationTree

Then the compiler is happy again. Sigh. It’s the little things that cause the grey hairs.

The second update was to add a checkbox that will add the -verbose switch to the NAnt call. As you’d expect, the additional messages generated will appear in the NAntRunner progress window. In previous version of NAntRunner, you could include this yourself using the “Other NAnt Args” box, but having a checkbox feeds my lazy side.

Third, I added the ability to reorder scripts within a group and moving scripts from one group to another – all via drag and drop. I found myself having to scan down through the groups looking for the right script more and more recently, and really wanted to be able to move the more commonly used ones to the top of the list. In the past you could always hack the NAntRunnerSettings.xml file to manually reorder these, but this is much more intuitive. Reordering entire groups and their contents isn’t available at this time.

The one item I didn’t plan on but ended up doing was reworking how the standard output and error messages were retrieved from the spawned NAnt process. Previously it was done at the end, once the NAnt task had completed. Version 0.4 does this asynchronously via event handlers – as the messages are generated. The reasons why and the details of the implementation will be a subject for a future post.

The future

I started thinking about what would define the 1.0 release. My goal with NAntRunner has always been to provide easier access to the common features of NAnt. I think it’s almost there. I may extend the “verbose” checkbox into a “message level” control (perhaps a slider) so NAntRunner has native support for the -verbose, -debug, and -quiet switches. I’ve also thought about adding logging support (using the -logger switch). Finally, I may extend the interface to allow you to save the NAntRunner configuration settings used for a given build script so that the next time you open that script NAntRunner will configure itself accordingly (saving you a few clicks and keystrokes).

Minimally, I’ve dropped several TODOs in the code for things that I need to get back to. Since many of these involve error handling, these are a must for version 1.0. If you can’t rely on your tools then you need better tools.

Enjoy the new release, and let me know what you think.