Showing posts with label .NET. Show all posts
Showing posts with label .NET. Show all posts

Thursday, March 30, 2017

C# String Interpolation Performance

Time for a follow up to my String.Concat vs String.Format Performance post from back in 2014!

I recently found out that string interpolation is not nearly as efficient as I would have thought. I also suspected that it was just doing a string concatenation, but it is actually doing a string format. This leads to a pretty significant performance degradation; the following test runs one million iterations of each.

Number
of Args
Interpolation
Milliseconds
String.Format
Milliseconds
String.Concat
Milliseconds
String Add
Milliseconds
StringBuilder
Milliseconds
2 262 260 19 18 34
3 367 367 25 24 35
4 500 513 31 32 41
5 646 635 67 66 44
6 740 723 79 76 49
7 802 819 86 85 52
8 938 936 97 98 58

So, what's the lesson? Don't use string interpolation in high performance areas (such as your logger)!

Enjoy,
Tom

Sunday, February 26, 2017

Run .NET Core xUnit tests from ReSharper in VS2015

Visual Studio 2017 is literally only a few days away from release; so it might be a little late, but I finally figured out how to run .NET Core xUnit tests from ReSharper in VS2015! Good News: If you can't upgrade to VS2017 right away, then at least you can still run your unit tests!

Just make sure that the following is included in your project.json file (with the appropriate runtime):

{
  "testRunner": "xunit",
 
  "dependencies": {
    "dotnet-test-xunit": "2.2.0-preview2-build1029",
    "xunit": "2.2.0"
  },
 
  "frameworks": {
    "netcoreapp1.0": {
      "imports": "dnxcore50"
    }
  },
 
  "runtimes": {
    "win10-x64": {}
  }
}

Enjoy,
Tom

Tuesday, January 31, 2017

.NET Standard Adoption as of January 2017

Updated 2/16 to include Elasticsearch

As should be obviously from my recently blog posts, I have really been enjoying working with .NET Core. Clearly I am not alone, as a significant number of libraries have been porting over to the .NET Standard.

Below is a list libraries that have added support for the .NET Standard, meaning that they should be able to run cross platform on both Windows and Linux.

While I have not yet had the opportunity to try all of the libraries listed below, I have had great luck with the ones that I have tested, and I am simply ecstatic to see this list growing as fast as it is.

Technology NuGet Package .NET Standard Support
Autofac Autofac Released for 1.1
Cassandra DataStax C# Driver for Apache Cassandra Released for 1.5
Couchbase Couchbase SDK 2.0 Beta for 1.5
Elasticsearch Elasticsearch.Net Released for 1.3
Kafka Confluent.Kafka Preview for 1.3
log4net Apache log4net Released for 1.3
MongoDB MongoDB.Driver Released for 1.4
NLog NLog Beta for 1.3
RabbitMQ RabbitMQ.Client Released for 1.5
RavenDB RavenDB Client Released for 1.3
Redis StackExchange.Redis Released for 1.5
Sqlite Microsoft.EntityFrameworkCore.Sqlite Released for 1.3
WebSocket Client WebSocket4Net Released for 1.3

How have these libraries been working out for you? Is there a better option than what I have listed? Please leave a comment and let me know!

Enjoy,
Tom

Sunday, January 29, 2017

.NET JsonContent for HttpClient

.NET already comes with a nice collection of HttpContent serializers, but it lacks a JsonContent type. A common solution is to just serialize their payload to a JSON string and that insert that into an instance of StringContent. However, this means that you need to remember to set your headers, and it is a little bit inefficient because of how it creates multiple strings and buffers for each payload.

I have create a simple implementation of JsonContent that uses Json.NET and pooled memory streams. The result is between 2% and 10% faster, and causes ~50% fewer garbage collections.

Check out the implementation in Tact.NET:

Enjoy,
Tom

Friday, December 30, 2016

Object Pooling and Memory Streams

The theme of this year, which I will talk about in my 2016 retrospective, has been optimization. It's been a fun journey, and I have really enjoyed getting down and dirty with profiling garbage collection, using spin waits, and aggressive inlining.

I want to end this year on a fun note: object pooling.

A great use case for this would be making HTTP requests with serialized objects. When you serialize an object, and then place it in a HttpContent object, you are probable creating several buffers (byte arrays) each time. For example, if you are using Newtonsoft to serialize an object and then adding that to a string content object for your request, then you are probably using more memory than you need. But that is getting ahead of ourselves...

Come back next week for a blog post about efficient JSON Content serialization!

For now, let's focus on building an object pool. Really all that we need is a preallocated array to store unused objects in, and then a super efficient thread safe data structure to pool (get and set) those objects.

How does pooling memory streams help us?

When you create a MemoryStream, it creates a byte array. As that byte array grows, the memory stream resizes it by allocating a new larger array and then copying your bytes into it. This is inefficient not only because it creates new objects and throws the old ones away, but also because it has to do the leg work of copying the content each time it resizes.

How can we reuse memory streams? Just set the length to zero!

Internally this will just set an index and empty the array, but the internal data structures will be preserved for future use. Thus, by putting memory streams into an object pool, we can drastically increase our efficiency.

Here is a demo of using the Tact.NET ObjectPool to pool MemoryStreams...

[Fact]
public void MemoryStreamPoolDemo()
{
    using (var pool = new ObjectPool<MemoryStream>(100, () => new MemoryStream()))
    {
        var memoryStream1 = pool.Acquire();
 
        memoryStream1.SetLength(0);
        Assert.Equal(0, memoryStream1.Capacity);
 
        memoryStream1.Write(new byte[] {1, 0, 1, 0, 1}, 0, 5);
 
        var array1 = memoryStream1.ToArray();
        Assert.Equal(5, array1.Length);
        Assert.Equal(1, array1.First());
        Assert.Equal(1, array1.First());
 
        pool.Release(memoryStream1);
 
        var memoryStream2 = pool.Acquire();
        Assert.Same(memoryStream1, memoryStream2);
 
        memoryStream2.SetLength(0);
        Assert.Equal(256, memoryStream2.Capacity);
 
        memoryStream2.Write(new byte[] { 0, 1, 0 }, 0, 3);
 
        var array2 = memoryStream2.ToArray();
        Assert.Equal(3, array2.Length);
        Assert.Equal(0, array2.First());
        Assert.Equal(0, array2.First());
    }
}

Enjoy,
Tom

Sunday, November 27, 2016

The Performance Cost of Boxing in .NET

I recently had to do some performance optimizations against a sorted dictionary that yielded some interesting results...

Background: I am used to using Tuples a lot, simply because they are easy to use and normally quite efficient. Please remember that Tuples were changed from structs to classes back in .NET 4.0.

Problem: A struct decreased performance!

I had a SortedDictionary that was using a Tuple as a key, so I thought "hey, I'll just change that tuple to a struct and reduce the memory usage." ...bad news, that made performance WORSE!

Why would using a struct make performance worse? It's actually quite simple and obvious when you think about it: it was causing comparisons to repeatedly box the primitive data structure, thus allocating more memory on the heap and triggering more garbage collections.

Solution: Use a struct with an IComparer.

I then created a custom struct and used that; it was must faster, but it was still causing boxing because of the non-generic IComparable interface. So finally I added a generic IComparer and passed that into my dictionary constructor; my dictionary then ran fast and efficient, causing a total of ZERO garbage collections!

See for yourself:

The Moral of the Story

Try to be aware of what default implementations are doing, and always remember that boxing to object can add up fast. Also, pay attention to the Visual Studio Diagnostics Tools window; it can be very informative!

Here is how many lines of code it took to achieve a 5x performance increase:

private struct MyStruct
{
    public MyStruct(int i, string s) { I = i; S = s; }
    public readonly int I;
    public readonly string S;
}
 
private class MyStructComparer : IComparer<MyStruct>
{
    public int Compare(MyStruct x, MyStruct y)
    {
        var c = x.I.CompareTo(y.I);
        return c != 0 ? c : StringComparer.Ordinal.Compare(x.S, y.S);
    }
}

Test Program

I have written some detailed comments in the Main function about what each test is doing and how it will affect performance. Let's take a look...

Saturday, November 26, 2016

10x faster than Delegate.DynamicInvoke

This is a follow up to my previous blog posts, Optimizing Dynamic Method Invokes in .NET, and Dynamically Invoke Methods Quickly, with InvokeHelpers.EfficientInvoke. Basically, I have re-implemented this for Tact.NET in a way that makes it smaller, faster, and compatible with the .NET Standard.

So, how much faster is this new way of doing things? EfficientInvoker.Invoke is over 10x faster than Delegate.DynamicInvoke, and 10x faster than MethodInfo.Invoke.

Check out the source on GitHub:

Simple Explanation

Here is an example of a method and a class that we might want to invoke dynamically...

public class Tester
{
    public bool AreEqual(int a, int b)
    {
        return a == b;
    }
}

...and then here is the code that the EfficientInvoker will generate at runtime to call that method:

public static object GeneratedFunction(object target, object[] args)
{
    return (object)((Tester)target).AreEqual((int)args[0], (int)args[1]);
}

See, it's simple!

Monday, October 31, 2016

Introducing Tact.NET

I have decided to create a project to consolidate all of the utilities that I have authored over the years on this blog...

Tact.NET - A tactful collection of utilities for .NET development.

I believe that this will give me the opportunity to update old code more often, as well as develop new utilities faster. For example, the there is already an ILog interface that optimizes (thank you, Jeremy) the Caller Information Extensions I wrote about about back in May.

Everything that I add to this project will be build for the .NET Standard Library, and should support .NET Core on all platforms. Expect to see NuGet packages soon, and hopefully many more blog posts to come.

Enjoy,
Tom

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.

Enjoy,
Tom

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
{
    [Fact]
    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);
            results.Enqueue(i);
        }, disposeTimeoutMs: 0))
        {
            processor.Enqueue(1);
            processor.Enqueue(2);
            processor.Enqueue(3);
            processor.Enqueue(4);
            processor.Enqueue(5);
 
            await Task.Delay(300).ConfigureAwait(false);
        }
 
        Assert.Equal(2, results.Count);
    }
 
    [Fact]
    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);
            results.Enqueue(tuple);
        }))
        {
            processor.Enqueue(1);
            processor.Enqueue(2);
            processor.Enqueue(3);
            processor.Enqueue(4);
            processor.Enqueue(5);
        }
 
        Assert.Equal(5, results.Count);
 
        var maxParallelism = results.Max(t => t.Item1);
        Assert.Equal(parallelism, maxParallelism);
    }
 
    [Fact]
    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);
            results.Add(tuple);
        }))
        {
            processor.Enqueue(1);
            processor.Enqueue(2);
            processor.Enqueue(3);
            processor.Enqueue(4);
            processor.Enqueue(5);
        }
 
        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...

InvokeHelpers.EfficientInvoke

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
            .GetType()
            .GetMethod(key.Item1);
 
        var argTypes = method
            .GetParameters()
            .Select(p => p.ParameterType)
            .Concat(new[] { method.ReturnType })
            .ToArray();
 
        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

Enjoy,
Tom

Thursday, June 30, 2016

Updating Default Parameters in .NET Assemblies

One of the things that I love about C# is how so many of it's features are just very conveniently designed compiler tricks. This means that, just like any other magic trick, once you know how the trick is performed you immediately realize that there really is nothing magical about it.

So, let's talk about default parameters. They are actually just constant values that get compiled into your code when you go to use a method that has them. Let's look at an example...

The Code

public enum Country
{
    US,
    CA
}
 
public static class SharedUtility
{
    public static bool CanDrink(
        int age, 
        Country country = Country.CA)
    {
        switch (country)
        {
            case Country.US:
                return age >= 21;
 
            case Country.CA:
                return age >= 18;
 
            default:
                throw new ArgumentException(
                    "Invalid Country",
                    nameof(country));
        }
    }
}
 
public class SharedUtilityTests
{
    [Fact]
    public void CanDrink()
    {
        var result = SharedUtility.CanDrink(20);
 
        // The line above will compile into the following:
        // var result = SharedUtility.CanDrink(20, Country.CA);
        // Thus, the Assert below will succeed!
 
        Assert.True(result, "The default was not US!");
    }
}

So, now that you know how the trick is performed, how could this cause a problem for you? Specifically, what happens if you update a library that exposes methods with default parameters?

Nothing will change, until you recompile against the library!

If another library changes their default parameters, but you do not recompile your code against it, then your code will be using the old default values! Let's look back at the previous example and see why this could cause confusion...

Wednesday, May 4, 2016

IResourceLoader: Balancing Semaphores

Recently I need to get balance getting resources from a restricted number of sources. So, for example...

I am getting resource R, and I have factories A, B and C creating those Rs. Each of those factories has a very limited capacity for creating those resources, and can only create two Rs at a time. It is easy to put the factories behind a semaphore and limit how many threads can be requesting resources from each factory at a time.

The challenge is evenly balancing the workload between all three factories. Also, please note that you can't just round robin the semaphores because there is no way to ensure that each operation will complete in the same amount of time.

To do this I created a generic IResourceLoader interface, and made two implementations: one to wrap a semaphore, and the other to wrap and balance a collection of IResourceLoaders. Below is the implementation, complete with unit tests; let's take a look!

Interface

public interface IResourceLoader<T>
{
    int Available { get; }
    int Count { get; }
    int MaxConcurrency { get; }
 
    Task<T> GetAsync(CancellationToken cancelToken = default(CancellationToken));
    bool TryGet(out Task<T> resource, CancellationToken cancelToken = default(CancellationToken));
}

Sunday, April 10, 2016

RangeSet for .NET

Update 4/13 - Added support for single value ranges.

What data structure do you use when you need to efficiently check if a number is within a large set of ranges?

If you require that the ranges do not overlap, then it is simple to keep a balanced binary tree of the ranges. Finding if a number is within one of those ranges should only take O(log n) to find. Below is an implementation of a RangedSet that uses a standard .NET SortedSet to store the ranges.

IRangeSet Interface

public interface IRangeSet<in T> where T : IComparable
{
    void AddRange(T min, T max);
 
    bool Contains(T findValue);
}

Friday, March 18, 2016

How to Release a Semaphore with a Using Block

I love that .NET has so many useful utilities available in the base framework. I often use the SemaphoreSlim, and I love that it supports async await. However, I don't like always having to create a try finally block around every use call to ensure that the release method gets called.

Below is a simple little extension method that will allow you to place the result of the Semaphore wait into a using block, thus ensuring that the dispose will always release the lock.

SemaphoreSlim Extensions

public static class SemaphoreSlimExtensions
{
    public static async Task<IDisposable> UseWaitAsync(
        this SemaphoreSlim semaphore, 
        CancellationToken cancelToken = default(CancellationToken))
    {
        await semaphore.WaitAsync(cancelToken).ConfigureAwait(false);
        return new ReleaseWrapper(semaphore);
    }
 
    private class ReleaseWrapper : IDisposable
    {
        private readonly SemaphoreSlim _semaphore;
 
        private bool _isDisposed;
 
        public ReleaseWrapper(SemaphoreSlim semaphore)
        {
            _semaphore = semaphore;
        }
 
        public void Dispose()
        {
            if (_isDisposed)
                return;
 
            _semaphore.Release();
            _isDisposed = true;
        }
    }
}

Sunday, February 21, 2016

Async Cache Repository v2

Three years ago (wow, time flies) I wrote a generic Cache Repository that has become one of my more popular open source projects. It is 2016, so was definitely time to create an async version of that cache repository! This new implementation has all of the same features as the original, only now it is completely async from top to bottom.

CacheRepository.Web

Features

  • Thread Safe GetOrSet
  • Configurable Expiration Enums
  • Transparent Cache Key Management By Type
  • A Web Implementation

NuGet Package and Source

Enjoy,
Tom

Monday, February 15, 2016

How To: Kill child process when parent process is killed v2

Working with unmanaged memory is not my forte. Thus I am very appreciative of when someone not only reads my blog, but then takes the time to do their own research and leave comments and suggest updates. TLDR: Thank you, Steven Pereyda!

Last year I blogged about how to kill a child process when the parent process is killed. The solution involves using the operating system by invoking Kenral32. However, as mentioned above, there was a small memory leak and a few other optimizations that we should have made; so let's take a look at how to fix those!

Fixes and Optimizations in v2

1. There was a small memory leak.

In the job constructor we used Marshal.AllocHGlobal to create an unmanaged copy of the JobObjectExtendedLimitInformation object, but we never freed that memory. The new constructor how has a finally block that ensures we invoke Marshal.FreeHGlobal.

2. We should use SafeHandles.

.NET has a SafeHandle class that can be used as a wrapper around unmanaged handles, which can help you prevent memory leaks; and I learned how to use this by reading a code project article by the always awesome Stephen Cleary. Please note that in v2 there is a now a JobObjectHandle class that extends SafeHandle, and we use this instead of storing the IntPtr ourselves.

3. We moved the GC.SuppressFinalize into the public dispose method.

Yes, this is the right way to do it. So why didn't I do it that way the first time? Because ReSharper was warning me that I wasn't using the isDisposing param...and hate warnings!

4. Follow the best practices of hosting all external calls in a single Native Methods class.

Microsoft recommends that you keep all of your external calls in one NativeMethods class, and then decorate that class with attributes to avoid security warnings. Sounds like a good idea to me.

Friday, January 22, 2016

C# Interfaces and Default Parameters

How does a default parameter work?

One of the things that I love about C# is how so many of it's features are just very conveniently designed compiler tricks. This means that, just like any other magic trick, once you know how the trick is performed you immediately realize that there is nothing magical about it all!

So, let's talk about default parameters. They are actually just constant values that get compiled into your code when you go to use a method that has them. Let's look at an example...

public class DefaultParamTests1
{
    [Fact]
    public void WhatYouWrite()
    {
        var actual = Double();
        Assert.Equal(2, actual);
    }
 
    private static int Double(int i = 1)
    {
        return i * 2;
    }
}
 
public class DefaultParamTests2
{
    [Fact]
    public void WhatItCompilesTo()
    {
        var actual = Double(1);
        Assert.Equal(2, actual);
    }
 
    private static int Double(int i)
    {
        return i * 2;
    }
}

What happens when interfaces and methods don't match?

So, now that you know how the trick is performed, what happens if you use a different default value for a parameter defined by an interface and a class?

The answer is simple: if your object is cast as the class, then it will use the class value. If your object is cast as the interface, it will use the interface value instead. Let's take a look at another example...

Real Time Web Analytics