Friday, September 30, 2016

Host HTTP and WebSockets on the Same Port in ASP.NET

How do you support WebSocket connections on the same port as your HTTP server in .NET? It turns out that this is not that hard, and you even have several choices to do so...

Option 1: TCP Proxy

You could use a TCP proxy port to divide traffic between the two targets. For example, all traffic would come in to port 80, but then HTTP traffic would be routed internally to 8001 and WS traffic to 8002. This is useful because it would allow you to use multiple technologies (in the example on their site, both NancyFX and Fleck) to host your web servers.

Option 2: SignalR

SignalR is great because of all the backwards compatibility that it supports for both the server and client. However, it is not the most lightweight framework. If you choose to use it, then it will absolutely support both HTTP and WS.

Option 3: Owin.WebSocket *My Favorite*

Owin supports WebSockets, and that is exactly what SignalR uses to host its WS connections. The awesome Mr. Bryce Godfrey extracted the Owin code from SignalR into a much smaller library called Owin.WebSocket.

The ONLY thing that I did not like about this implementation was that is uses inheritance to define endpoints, whereas I much prefer the ability to use delegates and lambdas. Because of this, I created Owin.WebSocket.Fleck, which allows you to use the Fleck API to map your WebSockets to an Owin context. A pull request is open to merge this into the main repository.


Sunday, September 25, 2016

.NET Asynchronous Parallel Batch Processor

Last year, I wrote about how to handle dynamically sized batches of data in an asynchronous manner. That original implementation used an abstract base class, and only supported a single background processing thread. I recently updated that implementation to support lambdas rather than requiring inheritance, and support a dynamic number of background threads.

...basically, this is a ConcurrentQueue that supports taking a lambda and thread count to asynchronously process enqueued items.

Unit Tests

public class ParallelProcessorTests
    public async Task NoDisposeTimeout()
        var results = new ConcurrentQueue<int>();
        using (var processor = new ParallelProcessor<int>(2, async (i, token) =>
            await Task.Delay(200, token).ConfigureAwait(false);
        }, disposeTimeoutMs: 0))
            await Task.Delay(300).ConfigureAwait(false);
        Assert.Equal(2, results.Count);
    public void MaxParallelizationLimit()
        const int parallelism = 3;
        var results = new ConcurrentQueue<Tuple<int, int>>();
        var active = 0;
        using (var processor = new ParallelProcessor<int>(parallelism, async (i, token) =>
            Interlocked.Increment(ref active);
            await Task.Delay(200, token).ConfigureAwait(false);
            var currentActive = Interlocked.Decrement(ref active) + 1;
            var tuple = Tuple.Create(currentActive, i);
        Assert.Equal(5, results.Count);
        var maxParallelism = results.Max(t => t.Item1);
        Assert.Equal(parallelism, maxParallelism);
    public void BatchProcessor()
        var results = new List<Tuple<long, List<int>>>();
        var sw = Stopwatch.StartNew();
        using (var processor = new BatchParallelProcessor<int>(1, 2, async (ints, token) =>
            await Task.Delay(100, token).ConfigureAwait(false);
            var tuple = Tuple.Create(sw.ElapsedMilliseconds, ints);
        Assert.Equal(3, results.Count);
        Assert.Equal(2, results[0].Item2.Count);
        Assert.Equal(1, results[0].Item2[0]);
        Assert.Equal(2, results[0].Item2[1]);
        Assert.True(results[0].Item1 < results[1].Item1);
        Assert.Equal(2, results[1].Item2.Count);
        Assert.Equal(3, results[1].Item2[0]);
        Assert.Equal(4, results[1].Item2[1]);
        Assert.True(results[1].Item1 < results[2].Item1);
        Assert.Equal(1, results[2].Item2.Count);
        Assert.Equal(5, results[2].Item2[0]);

Sunday, August 21, 2016

Dynamically Invoke Methods Quickly, with InvokeHelpers.EfficientInvoke

In my previous blog post, I talked about Optimizing Dynamic Method Invokes in .NET. In this post, we will use that information to create a static helper method that is twice as fast as MethodInfo.Invoke.

Basically, we create and cache a delegate in a concurrent dictionary, and then cast both it and it's arguments to dynamics and invoke them directly. The concurrent dictionary introduces overhead, but it still more than twice as fast as calling MethodInfo.Invoke. Please note that this method is highly optimized to reduce the use of hash code look ups, property getters, closure allocations, and if checks.

let's take a look at the code...


public static class InvokeHelpers
    private const string TooManyArgsMessage = "Invokes for more than 10 args are not yet implemented";
    private static readonly Type VoidType = typeof(void);
    private static readonly ConcurrentDictionary<Tuple<string, object>, DelegatePair> DelegateMap 
        = new ConcurrentDictionary<Tuple<string, object>, DelegatePair>();
    public static object EfficientInvoke(object obj, string methodName, params object[] args)
        var key = Tuple.Create(methodName, obj);
        var delPair = DelegateMap.GetOrAdd(key, CreateDelegate);
        if (delPair.HasReturnValue)
            switch (delPair.ArgumentCount)
                case 0: return delPair.Delegate();
                case 1: return delPair.Delegate((dynamic)args[0]);
                case 2: return delPair.Delegate((dynamic)args[0], (dynamic)args[1]);
                case 3: return delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2]);
                case 4: return delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3]);
                case 5: return delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3], (dynamic)args[4]);
                case 6: return delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3], (dynamic)args[4], (dynamic)args[5]);
                case 7: return delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3], (dynamic)args[4], (dynamic)args[5], (dynamic)args[6]);
                case 8: return delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3], (dynamic)args[4], (dynamic)args[5], (dynamic)args[6], (dynamic)args[7]);
                case 9: return delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3], (dynamic)args[4], (dynamic)args[5], (dynamic)args[6], (dynamic)args[7], (dynamic)args[8]);
                case 10: return delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3], (dynamic)args[4], (dynamic)args[5], (dynamic)args[6], (dynamic)args[7], (dynamic)args[8], (dynamic)args[9]);
                default: throw new NotImplementedException(TooManyArgsMessage);
        switch (delPair.ArgumentCount)
            case 0: delPair.Delegate(); break;
            case 1: delPair.Delegate((dynamic)args[0]); break;
            case 2: delPair.Delegate((dynamic)args[0], (dynamic)args[1]); break;
            case 3: delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2]); break;
            case 4: delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3]); break;
            case 5: delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3], (dynamic)args[4]); break;
            case 6: delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3], (dynamic)args[4], (dynamic)args[5]); break;
            case 7: delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3], (dynamic)args[4], (dynamic)args[5], (dynamic)args[6]); break;
            case 8: delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3], (dynamic)args[4], (dynamic)args[5], (dynamic)args[6], (dynamic)args[7]); break;
            case 9: delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3], (dynamic)args[4], (dynamic)args[5], (dynamic)args[6], (dynamic)args[7], (dynamic)args[8]); break;
            case 10: delPair.Delegate((dynamic)args[0], (dynamic)args[1], (dynamic)args[2], (dynamic)args[3], (dynamic)args[4], (dynamic)args[5], (dynamic)args[6], (dynamic)args[7], (dynamic)args[8], (dynamic)args[9]); break;
            default: throw new NotImplementedException(TooManyArgsMessage);
        return null;
    private static DelegatePair CreateDelegate(Tuple<string, object> key)
        var method = key.Item2
        var argTypes = method
            .Select(p => p.ParameterType)
            .Concat(new[] { method.ReturnType })
        var newDelType = Expression.GetDelegateType(argTypes);
        var newDel = Delegate.CreateDelegate(newDelType, key.Item2, method);
        return new DelegatePair(newDel, argTypes.Length - 1, method.ReturnType != VoidType);
    private class DelegatePair
        public DelegatePair(dynamic del, int argumentCount, bool hasReturnValue)
            Delegate = del;
            ArgumentCount = argumentCount;
            HasReturnValue = hasReturnValue;
        public readonly dynamic Delegate;
        public readonly int ArgumentCount;
        public readonly bool HasReturnValue;

Now let's take a look at some performance tests...

Optimizing Dynamic Method Invokes in .NET

I recently had a lot of fun helping to optimize some RPC code that was using reflection to dynamically invoke methods in a C# application. Below are a list of implementations that we experimented with, and their performance.

  1. Directly Invoking the Method
  2. Using MethodInfo.Invoke
  3. Using Delegate.DynamicInvoke
  4. Casting to a Func
  5. Casting a Delegate to Dynamic

Spoilers: Here are the results. (The tests for this can be see below.)

Name First Call (Ticks) Next Million Calls Invoke Comparison
Invoke 1 39795 -
MethodInfo.Invoke 12 967523 x24
Delegate.DynamicInvoke 32 1580086 x39
Func Invoke 731 41331 x1
Dynamic Cast 1126896 85495 x2

Conclusion: Invoking a method or delegate directly is always fastest, but when you need to execute code dynamically, then (after the first invoke) the dynamic invoke of a delegate is significantly faster than using reflection.

Let's take a look at the test code...

Sunday, July 31, 2016

Can I port my application to .NET Core?

I am very excited about .NET Core, and I am looking forward to porting my projects to it. Generally porting your own code is a straight forward task, but updating all of your dependencies can be quite daunting. Good news: the guys over at Octopus have built an awesome little site that helps you determine the state of your dependencies!

I Can Has .NET Core


Sunday, July 24, 2016

Make your NuGet Server use NLog

The latest version of NuGet.Server is fast, stable, and super simple to setup. As for most .NET tools, Scott Hanselman already create a great write up about how to use it.

However, I was very disappointed at how unintuitive it was to get wire up a custom logger!

You need to take several steps to make the official NuGet server write to something like NLog:

  1. Create a log wrapper.
  2. Implement NuGet.Server.Logging.ILogger.
  3. Implement NuGet.ILogger...
  4. ...which also makes you implement NuGet.IFileConflictResolver!
  5. Implement your own NuGet.Server.IServiceResolver
  6. When instantiating ServerPackageRepository...
  7. ...pass in the ILogger...
  8. ...AND set the Logger property!

Still confused? Pull the code here, or take a look below!

Sunday, July 17, 2016

Should you open source your software?

Every Tuesday I help host the QQ Cast, where we fabricate answers to geek culture's most superfluous questions. For our 50th Quest, my good friend Matt Stevenson joined us to talk about open source software.

QQ Cast - Quest 50 - Should you open source your software?

  • 00:00 - Mic Check and Introductions
  • 05:30 - Is "Expand Enhance Extinguish" still alive and well?
  • 19:40 - Can we build a sustainable infrastructure without open source software?
  • 33:00 - How much structure do we like to see in our frameworks?
  • 40:50 - What are some great open source projects?
  • 47:15 - Was heartbleed a good thing or a bad thing?
  • 54:30 - Does contributing to open source projects help your resume?
  • 60:00 - Should you open source your software?
  • 70:00 - Wrap up!

Please always remember that all views and opinions expressed on the podcast are representative solely of the person expressing them; not of their friends and family, not of their coworkers, and certainly not of their employers, past, present, or future.


Real Time Web Analytics