Thursday, March 31, 2016

xUnit.net: Extensions Config v3.3.0

I recently made several updates to the xunit.extensions.config library, which allows you to configure theory data from your app.config file. Here are the links to the source and the NuGet package:

New Features

  • Named Parameter Support

You no longer need to configure your data by parameter index. You can now name your data for each parameter, making the configuration much easier to read and understand.

  • AppSettings Support

You can now use the standard AppSettings section of the App.config to configure your data. If no settings are found, then the framework will fallback to trying to use the standard config section.

  • Default Namespace Option

You can now provide a default namespace for your tests. This reduced the amount of redundant text in your config file, and makes test names much more concise and easy to read.

  • Extensible Data Provider

Don't want to use the existing data providers? Would you rather use a database? Now you can! Just add an AppSettings key for "TestData.ServiceFactory" that provides the fully qualified name of a static method that returns an IConfigTestDataService, and the framework will try to use that to load configuration data.

Wednesday, March 30, 2016

Why method that return a Task should end with Async

I have spoken before about using the Fleck WebSocket server library for .NET, but recently I experienced a small problem with it. Pull request #126 changed several public methods to become async and return a Task instead of void.

This did not follow the recommended naming convention of naming all async methods with the Async suffix.

In my case, this caused us to introduce a bug to a project that was using Fleck. We would ignore Task returned from IWebSocketConnection.Send, and under high load the task scheduler would get backed up.

Even though I do not think that they are going to use it, I created a pull request that updated the the public methods to include the Async suffix. Also, in order to maintain backwards compatibility, I also added obsolete methods to the interfaces without the suffix.

What did I do with the tasks? Rather than write in parallel, I used a concurrent queue and had a background task serially write messages to the connection.

Enjoy,
Tom

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;
        }
    }
}
Real Time Web Analytics