Rory Primrose

Learn from my mistakes, you don't have time to make them yourself

View project on GitHub

Splitting up arguments with a regular expression

There have been several times when I have needed to process a string that contains a set of arguments. It always seems to be a lot of work splitting up arguments by using white space as a delimiter because you need to take into account white space that is surrounded by brackets.

Just for kicks, I tried to come up with a regular expression that would do just that. Here is the result.

[^\s"]*"[^"]*"[^\s"]*|[^\s"]+
Read More

SQLEXPRESS fails to start

I have just encountered a problem where the SQLEXPRESS instance installed on my machine was not starting. It looks like a recent windows update has failed, but also knocked out SQL Server. The event log contains the following entry:

Error 3(error not found) occurred while opening file ‘C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\master.mdf’ to obtain configuration information at startup. An invalid startup option might have caused the error. Verify your startup options, and correct or remove them if necessary.

After searching around, there seems to be lots of forum posts going back several years about this issue. The problem is that the only known solution seems to be to change the credentials of the SQLEXPRESS service account to Local System. This will then allow the service to start. Doing this through the services console presents a problem however because you can’t set the service credentials back to Network Service as you need to know the password.

Read More

Troubleshooting DataDude deployment with TeamBuild

I’m working through the best way of getting DataDude to build and deploy a database using TeamBuild. When I kicked off a build, the build script failed with the following error:

Task "SqlBuildTask"   
  Building deployment script for [DatabaseName] : AlwaysCreateNewDatabase, EnableFullTextSearch, BlockIncrementalDeploymentIfDataLoss   
MSBUILD : Build error TSD158: Cannot open user default database. Login failed.   
MSBUILD : Build error TSD158: Login failed for user '[TeamBuildUserName]'.   
Done executing task "SqlBuildTask" -- FAILED.
Read More

Guidance on use of include in XML documentation comments

I have previously posted about using the include element for my XML documentation in cases where there is duplicated content. After a recent code review, the reviewer commented that the include element made it difficult to read the documentation because large parts of the XML documentation were abstracted out to an XML file. This made me look at ways around this and the affect of the include tag had on the tooling support.

As a quick overview, the include element in XML documentation tells the compiler to go to the specified XML file and run an XPath query (recursively). It pulls in the result of that XPath query and injects the content into the XML documentation being generated for a code element.

Read More

Tracing Performance Tips

I have recently been working with tracing performance and have posted several tidbits of information. Here is the overview.

  1. Use TraceSource instead of Trace
  2. Disable global locking
  3. Clear the default listener in configuration
  4. Don’t collect stacktrace information if not required
  5. Create TraceSource instances once per name and cache for reuse. I have encountered memory leaks from creating large numbers of instances of the same TraceSource name.
  6. Create a unique TraceSource and TraceListener for each logical part/tier/layer of the application (locking performance and data segregation)
  7. Use thread safe listeners if possible
  8. Check TraceSource.Switch.ShouldTrace before calculating any expensive information to provide to the trace message

On a side note, don’t forget to turn off code coverage for running load tests.

Read More

Don't trace the callstack if you don't need to

Here is another performance tip with tracing. In configuration, there is the opportunity to define some tracing options. These options determine the actions taken by TraceListener when it writes the footer of the trace record for a given message. One of the options is to output the Callstack.

It takes a bit of work to calculate the callstack. If you don’t need that information, then don’t configure your listeners to calculate it.

To demonstrate the difference, I created two load tests that each ran a unit test that used its own specific TraceSource. The reason for two separate load tests was to avoid a locking issue that would impact the results.

Here is the configuration I used:

Read More

Carrying tracing weight you didn't know you had

Continuing on my performance testing of tracing components, there is another factor I realised that may be impacting the performance I get out of my code.

When the TraceSource.Listeners property is referenced, the collection is initialised using the application configuration. Regardless of whether there is a TraceSource configured for the provided name or what listeners are defined, there is always a default listener that is added to the configured collection of listeners. This is the System.Diagnostics.DefaultTraceListener.

All the tracing methods of this listener implementation call down to an internalWrite method that has the following implementation:

Read More

Authoring xml documentation for Visual Studio and Sandcastle

This page has a great resource for writing xml documentation for code in Visual Studio and Sandcastle. It outlines the differences between the xml support of Visual Studio and Sandcastle. It is a great resource especially because Visual Studio doesn’t understand all the xml elements supported by Sandcastle. The document is now a year and a half old, but is still very accurate as the Visual Studio xml documentation schema and Sandcastle support haven’t changed much (if at all) since.

Read More

Disable Trace UseGlobalLock For Better Tracing Performance

I have had a performance bottleneck in a load test that I have been running. The load test run against some tracing components which ultimately invoke TraceSource and TraceListener methods. I have been wondering why performance drops through the floor as more and more users come online and the call count increases. I have used Reflector a lot of times to review the implementation of TraceSource and TraceListener to get a feel for what they do. I remembered that global locking may be a problem.

The methods on TraceSource check TraceInternal.UseGlobalLock (also referenced by Trace.UseGlobalLock) which is determined by the system.diagnostics/trace/useGlobalLock configuration value:

Read More