Easily measure performance of methods in .NET with MethodTimer

When developing applications in .NET, it’s wise to measure performance. While there are tools like performance counters available, they are simply too complex to set up and I hardly see anyone use them. The most used feature is the code below:

The downside of this is that it makes your code ugly to read (code waste) and you need to handle every return statement in the method to stop the stopwatch.

MethodTimer to the rescue

Simon Cropp has written a very nice weaver for Fody called MethodTimer that allows you to inject the stopwatch code above into any method by simply decorating it with an attribute.

Then it will be weaved into this:

Note that the code will take care of all return statements in the method, so all will be handled. Installing is super easy, just install the MethodTimer.Fody NuGet package.

Full support for async methods

Regular methods are easy, but what about async methods? They use state machines and there can be a lot of situations where the method can be returned. Starting with v1.15, async methods are fully supported. For example, the code below has a lot of return statements combined with await:

As you can see this method contains several return statements (before and after await statements), but will handle all situations. Measuring the duration of an (async) method has never been this easy!

GitLink 2.0 – making .NET open source accessible!

I am very proud to announce GitLink 2.0, the tool that will make open source code more accessible! This release is a major release introducing many new features and improvements. One of the improvements is support for more providers than GitHub, so I have renamed GitHubLink to GitLink.

First things first: this release wouldn’t be what it is now without the help of my friend Peter Kiers who saw the potential and lifted the product to a higher level.

Supporting more providers

As soon as we released GitHubLink, it went popular among open-source developers on GitHub. However, some people requested support for other providers such as BitBucket. This gave us the idea to create a generic approach where we could automatically detect the provider and find the right information. As of now, the following providers are supported:

  • BitBucket
  • GitHub

Are you interested in supporting a provider? Help us out with a pull request, it’s really easy!

Supporting more project types

GitHubLink supported both C# and Visual Basic projects. Starting with GitLink 2.0, all project types that Visual Studio can load are supported such as C++ and F#.

Improved performance

One of the downsides of GitHubLink was that it downloaded the whole repository in order to retrieve the latest commit SHA. GitLink 2.0 automatically determines whether there is a local .git folder. If so, it won’t even go to the official url to retrieve the latest commit but will use the local repository. If there is no local .git file, GitLink 2.0 will only fetch the latest commit and will no longer download any files from the remote repository resulting in much better performance.

Introducing PDB file verifications

Starting with GitLink 2.0, all PDB files are now verified before being updated. This means that GitLink checks whether all files inside the PDB file are actually available and contain the right hash.

Removing the F# and SourceLink dependencies

GitHubLink heavily relied on SourceLink, an F# implementation to update the PDB files to allow a custom source server. It was however hard to combine the world of F# and C# and we always had to ship the 2 assemblies with GitHubLink. In GitLink 2.0, the dependencies are no longer required and all logic is translated to C#. This improvement saves about 500 kb on the final GitLink assembly size.

How to get GitLink

You can download GitLink 2.0 here. It is also available on NuGet and Chocolatey. Note that if you have used GitHubLink in the past, we will be keeping compatibility packages for that until version 3.0. It’s best to update to GitLink as soon as possible.

Workspace management in C#

Recently I was working on a few projects that required the management of workspaces. Workspaces is a fancy term for a document, a list of documents or anything in between. I noticed that I was implementing the same logic over and over again so decided to create a library (and NuGet package) from the experiences.

The Orc.WorkspaceManagement package is currently in prerelease but I use it in several products.

The workspace management library makes it easy to manage workspaces. The main component is the IWorkspaceManager that contains the current workspace and allows to load or save a workspace. Note that this library does not force you to use a specific workspace location of any sort, so it can even be a database or server call to read / write the workspace.

Below is an overview of the most important components:

  • IWorkspace => the actual workspace object
  • IWorkspaceManager => the workspace manager with events and management methods
  • IWorkspaceInitializer => allows customization of initial settings of a workspace
  • IWorkspaceReader => reads a workspace from a location
  • IWorkspaceWriter => writes a workspace to a location

Creating a workspace

A workspace is a model that can be implemented by the developer and must implement the IWorkspace interface. The most convenient way to implement a workspace is by deriving from the WorkspaceBase class:

Creating a workspace initializer

When a workspace manager is created, it doesn’t contain anything. The IWorkspaceInitializer interface allows the customization of that state.

By default the following initializers are available:

  • EmptyWorkspaceInitializer => initializes nothing, this is the default
  • DirectoryWorkspaceInitializer => First checks if there is an app config setting called DataLocation. If so, it will use that. If not, it will fall back to %AppData%\[assembly company]\[assembly product]\data. Then it will also check if a command line directory is passed (first argument). If so, all previous will be overriden by the command line directory.

To create a custom workspace initializer, see the example below:

Next it can be registered in the ServiceLocator (so it will automatically be injected into the WorkspaceManager):

Make sure to register the service before instantiating the IWorkspaceManager because it will be injected

Creating a workspace reader service

Workspaces must be read via the IWorkspaceReaderService. The workspace manager automatically knows when to read a workspace. First, one must create a workspace reader as shown in the example below:

Next it can be registered in the ServiceLocator (so it will automatically be injected into the WorkspaceManager):

Creating a workspace writer service

Next it can be registered in the ServiceLocator (so it will automatically be injected into the WorkspaceManager):

Retrieving a type instance of the workspace

The library contains extension methods for the IWorkspaceManager to retrieve a typed instance: