Sunday, December 14, 2014

How much does RegexOptions.Compiled improve performance in .NET?

Just how much does the RegexOptions.Compiled flag improve regular expression performance in .NET? The answer: a lot! People have spoken about this before, but below are some more numbers to how you just how much it matters!

Performance Stats

Character Count Regex Pattern
1
[a-z]
3
[b-y].[1-8]
5
[b-y].[c-x].[1-8].[2-7]
7
[b-y].[c-x].[d-w].[1-8].[2-7].[3-6]
9
[b-y].[c-x].[d-w].[e-v].[1-8].[2-7].[3-6].[4-5]

RegexOptions 1 3 5 7 9
None 234176 285067 653016 690282 687343
Compiled 193945 235213 430609 452483 454625
Percent Gain 17% 17% 34% 34% 34%

Saturday, November 29, 2014

.NET 4.5 HttpClient is Thread Safe

Good news everyone, the .NET 4.5 HttpClient is thread safe!

This means that you can share instances of your HttpClients across your entire application. This is useful in that it allows you to reuse persisted connections. One of the best ways to do this is to create a class that can manage the object lifetime of those clients for you.

Below is a simple HttpClientManager that will create one HttpClient per authority. Why per authority? Because you might have to have different settings or credentials for different websites.

Sample Unit Tests

public class HttpClientManagerTests
{
    [Fact]
    public void GetForAuthority()
    {
        using (var manager = new HttpClientManager())
        {
            var client1 = manager.GetForAuthority("http://tomdupont.net/");
            var client2 = manager.GetForAuthority("https://tomdupont.net/");
            Assert.Same(client1, client2);
 
            var client3 = manager.GetForAuthority("http://google.com/");
            Assert.NotSame(client1, client3);
        }
    }
 
    [Fact]
    public void TryRemoveForAuthority()
    {
        const string uri = "http://tomdupont.net/";
 
        using (var manager = new HttpClientManager())
        {
            Assert.False(manager.TryRemoveForAuthority(uri));
 
            manager.GetForAuthority(uri);
 
            Assert.True(manager.TryRemoveForAuthority(uri));
 
        }
    }
}

Friday, November 28, 2014

Web API - Return Correct Status Codes for Exceptions

Returning the appropriate HTTP Response Codes back from your web server is a very important best practice. Fortunately for .NET developers, Web API makes it very easy to use Exception Filters to return the appropriate response codes from your exceptions.

By implementing a custom ExceptionFilterAttribute you can generically create and return HttpResponseMessages for unhandled exceptions based on type. This is great in that you do not have to wrap all of your controller actions in try catch blocks to handle exceptions from other application layers.

Sample Controller

public class ValuesController : ApiController
{
    public string Get(int id)
    {
        switch (id)
        {
            case 1:
                throw new KeyNotFoundException("Hello World");
 
            case 2:
                throw new ArgumentException("Goodnight Moon");
 
            default:
                return "value";
        }
    }
}

Saturday, November 22, 2014

Web API - Bad Request when Model State is Invalid

When you using Web API, would you like to always return a 400 (bad request) response whenever the model state is invalid? It is easy, just add the following filter attribute to your global list:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, 
    AllowMultiple = false, 
    Inherited = true)]
public class InvalidModelStateFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (!actionContext.ModelState.IsValid)
        {
            actionContext.Response = actionContext.Request.CreateErrorResponse(
                HttpStatusCode.BadRequest, 
                actionContext.ModelState);
        }
    }
}

Enjoy,
Tom

Saturday, November 15, 2014

AutoCancellationTokenSource

With the following code you can create a CancellationTokenSource that will signal cancellation on dispose. This provides an alternative to having to wrap a normal CancellationTokenSource in a try finally block.

Code

public class AutoCancellationTokenSource : CancellationTokenSource
{
    private bool _isDisposed;
 
    public AutoCancellationTokenSource()
    {
    }
 
    public AutoCancellationTokenSource(params CancellationToken[] linkedTokens)
    {
        foreach (var linkedToken in linkedTokens)
            if (linkedToken.IsCancellationRequested)
                TryCancel();
            else
                linkedToken.Register(TryCancel, false);
    }
 
    protected override void Dispose(bool disposing)
    {
        if (_isDisposed)
            return;
 
        TryCancel();
 
        base.Dispose(disposing);
 
        _isDisposed = true;
    }
 
    private void TryCancel()
    {
        if (!_isDisposed && !IsCancellationRequested)
            Cancel();
    }
}

Friday, October 31, 2014

FireAndForget a Task with AggressiveInlining

When working with tasks you will get a warning if you do not use a task returned from a method. However, you might actually want to fire and forget that task. So what do you do?

One option is to create an extension method for your task to mark it as fire and forget. Aside from removing the warning, it also gives you the nice ability to find all usages.

When creating this method it is a good idea to mark it with the aggressive inlining attribute. This will cause the compiler to try and inline the method to try and optimize performance.

Implementation and Unit Test

public static class TaskExtensions
{
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FireAndForget(this Task task)
    {
        // Do Nothing
    }
}
 
public class TaskExtensionTests
{
    [Fact]
    public void FireAndForget()
    {
        Task
            .Delay(100)
            .ContinueWith(t =>
            {
                // TODO: Stuff!
            })
            .FireAndForget();
    }
}

Enjoy,
Tom

Thursday, October 30, 2014

Real Time Web Analytics