.Net Stopwatch Returns Negative Elapsed Time

The System.Diagnostics.Stopwatch class in the .Net runtime can be used to time operations. Bit there’s a problem in .Net 3.5 and earlier. The Elapsed* properties (Elapsed, ElapsedMilliseconds, ElapsedTicks) will sometimes return a negative value.

There’s a note in the documentation:

On a multiprocessor computer, it does not matter which processor the thread runs on. However, because of bugs in the BIOS or the Hardware Abstraction Layer (HAL), you can get different timing results on different processors. To specify processor affinity for a thread, use the ProcessThread.ProcessorAffinity method.

Some advocate setting processor affinity to eliminate the possibility of a negative elapsed time. But a common work-around is to simply use zero whenever the elapsed time is negative.

In recent work I used the Stopwatch class to time operations performed by Threads in a ThreadPool and I was getting false timings because of the negative elapsed time issue. I was leery of messing with the threads’ processor affinities because the ThreadPool is a shared resource. But I had concerns about the ‘convert to zero’ work-around.

Through a Microsoft contact I was able to confirm that the work-around of checking for ‘elapsed < 0’ is adequate. The negative time issue occurs only when measuring very small time periods. The issue is fixed in .Net 4.0 and the fix in the Stopwatch is to check that if elapsed < 0 then set elapsed to zero.

Hacking SLN Files to Improve Visual Studio/Visual Source Safe Integration

There are some who think Microsoft Visual Source Safe (VSS) is great. There are some who think that it’s not great but it is pretty good. And there are some who think Source Safe is just good enough. I am not among any of those groups.

One pain point with Source Safe in a Microsoft tool chain is integration with Visual Studio. Historically Visual Studio has stored source control information directly in the solution and project files. This reveals itself to be a really terrible idea the first time a project or solution file is shared in Source Safe. Checkouts from within the IDE will use the the source control bindings in the solution or project. If the solution or project file has been shared and not changed the bindings will be pointing to the original location in Source Safe. Checking out through Visual Studio will checkout the wrong file.

Yes, the solution and project files can be branched and the bindings updated. That’s sub-optimal. It means branching just to fix a tool problem and not because of any actual divergence in the code base. Any non-divergent changes to the solution or project must then be manually propagated to all the branched versions. Ugh.

The problem has not gone unnoticed at Microsoft. Over time and new releases of VStudio and VSS, improvements have been made.

My current position of employment is not using the latest and greatest. We’re on Visual Studio 2005 and Visual Source Safe 2005. The code base is in C#. I worked out a way to have shared solution and project files for non-web projects. Web projects in 2005 are different beasts and don’t follow the same rules. If you are using different versions of Visual Studio or Visual Source Safe your mileage will vary.

When getting files from VSS into a working directory, Visual Source Safe 2005 will create or update a mssccprj.scc file if any of the files present include a solution (.sln) or project file (for C#, .csproj). The mssccprj.scc file is a text file and it will contain the VSS bindings for the solution and project files that are in the same directory as the mssccprj.scc file.

In Visual Studio 2005, project files by default use the special ‘SAK’ string in the project file settings for VSS bindings. SAK indicates to Visual Studio that the bindings in the mssccprj.scc file should be used. The mssccprj.scc bindings are based on the directory retrieved from Source Safe. This means that shared project files just work. Yay.

In 2005 the problem is with solution files.

More specifically the problem is with solution files that include project files that are not in the same directory as the solution file. Creating a MyHelloWorld project will create a MyHelloWorld.sln and a MyHelloWorld.csproj in a MyHelloWorld directory. The .sln will reference the .csproj by name only and both files will have bindings in the mssccprj.scc file in the same directory and that all works without issue. But create a blank solution and add multiple existing projects to it and Visual Studio 2005 reverts to storing specific VSS bindings for the projects in the solution file.

There’s a work-around but it doesn’t work for parenting paths. Any time a solution references a project where the path to the project file starts with ‘..’, Visual Studio will revert to storing a VSS binding in the solution file. Because of this limitation it becomes convenient to have a convention that solution files generally go in the root of the code base tree.

The goal is to get the VSS bindings out of the solution file and have Visual Studio rely on the mssccprj.scc file. I haven’t found a reliable way to do this from within the IDE with existing projects but the solution (.sln) files are just text files, so I hack them.

Here’s a snippet from a .sln file. In Source Safe, the solution file is in “$/CodeBase v1”. There are two projects: a class library and a windows application. The SccProjectName<N> values are bindings to specific locations in the source safe repository. These are the bindings that need to be removed.


Global
GlobalSection(SourceCodeControl) = preSolution
SccNumberOfProjects = 3
SccLocalPath0 = .
SccProjectUniqueName1 = ClassLibrary1\\ClassLibrary1.csproj
SccProjectName1 = \u0022$/CodeBase\u0020v1/ClassLibrary1\u0022,\u0020TAAAAAAA
SccLocalPath1 = ClassLibrary1
SccProjectUniqueName2 = WindowsApplication1\\WindowsApplication1.csproj
SccProjectName2 = \u0022$/CodeBase\u0020v1/WindowsApplication1\u0022,\u0020WAAAAAAA
SccLocalPath2 = WindowsApplication1
EndGlobalSection

The .sln file can be edited to remove the SccProjectName<N> values but the SccLocalPath<N> must be updated to ‘.’ and a new property, SccProjectFilePathRelativizedFromConnection<N>, must be added with the old local path value and an appended directory separator.


Global
GlobalSection(SourceCodeControl) = preSolution
SccNumberOfProjects = 3
SccLocalPath0 = .
SccProjectUniqueName1 = ClassLibrary1\\ClassLibrary1.csproj
SccLocalPath1 = .
SccProjectFilePathRelativizedFromConnection1 = ClassLibrary1\\
SccProjectUniqueName2 = WindowsApplication1\\WindowsApplication1.csproj
SccLocalPath2 = .
SccProjectFilePathRelativizedFromConnection2 = WindowsApplication1\\
EndGlobalSection

Reference: Alin Constantin’s blog: The SAK source control strings in Visual Studio’s project files

Internet Explorer's Maximum URL Length

Note to self: Internet Explorer has a maximum URL size limit of 2,083 characters. Passing a longer URL (like maybe a URL with a dynamically built query string) to IE 7.0 will produce a cryptic error page (even with ‘Friendly’ turned off) that says “Internet Explorer cannot display the webpage” and then misleadingly suggests that the server can not be reached. Don’t waste time troubleshooting network connections or DNS lookups. Don’t be puzzled by why the same URL works in FireFox and Safari.