Category Archives: Uncategorized

Manual Validation in A Mediatr RequestHandler without Exceptions

This is the second post in a 2 post series:

  1. Validation without Exceptions using a MediatR Pipeline Behavior; and
  2. Manual Validation in A Mediatr RequestHandler without Exceptions

In my last post, I covered a scenario of using a Mediatr Pipeline Behavior to perform validation of a command object in such a way that no exception is thrown in the event of a validation failure. Today, I’m going to cover another strategy which involves manual validation in the Business Layer, rather than handing it off to the framework (as described in that previous post).

There may be times where you need to perform manual validation in the business layer, for one reason or another. Perhaps some code needs to run before the validation is performed and this may not be something which can happen if the validation happens automatically in the Mediatr pipeline. In such a case, we are faced with the same challenge as in my previous post; how do we bubble a validation failure up to the View, without just doing the throw/catch exception thing?

The solution which I’m putting forward in this post uses a Functional Programming construct known as a Discriminated Union. But we’ll get to that in time. First I’ll set out the scenario. I’ll try to keep it simple, yet at the same time keep a realistic number of layers to be comparable to a real world application.

The trivial example which I will present will involve a simple validator which merely validates whether a collection of Colors is not empty. Again, using FluentValidation, such a validator would look like this:

public class ColourCollectionValidator : AbstractValidator<IEnumerable<ColourPayloadDto>>
{
	public ColourCollectionValidator()
	{
		RuleFor(c => c)
			.Must(c => c.Any())
			.WithMessage("The payload must contain at least one colour.");
	}
}

So, lets look at the service which will perform the validation. The relevant method in this service will need to return both the ValidationResult and the collection itself. For that, I will use the ValueTuple type, which is a handy data-structure which helps us keep down the number of DTOs in our project (we will have enough DTOs already, without having to create another little one for this little job).

public class ColoursService : IColoursService
{
	private readonly IValidator<IEnumerable<ColourPayloadDto>> _colourValidator;

	public ColoursService(IValidator<IEnumerable<ColourPayloadDto>> colourValidator)
	{
		_colourValidator = colourValidator;
	}

	public async Task<(ValidationResult ValidationResult, List<ColourPayloadDto> DTOs)> GetColoursAsync()
	{
		/************* NOTE: hard coding a list here. Would normally be populated by database or API call *************/
		var colourPayloadDtos = new List<ColourPayloadDto>
		{
			new ColourPayloadDto{ Id = Color.Gainsboro.ToArgb(), IsKnownColour = Color.Gainsboro.IsKnownColor, Colour = Color.Gainsboro.Name},
			new ColourPayloadDto{ Id = Color.SaddleBrown.ToArgb(), IsKnownColour = Color.SaddleBrown.IsKnownColor  ,Colour =Color.SaddleBrown.Name},
			new ColourPayloadDto{ Id = Color.PaleGreen.ToArgb(), IsKnownColour = Color.PaleGreen.IsKnownColor,Colour= Color.PaleGreen.Name},
			new ColourPayloadDto{ Id = Color.DarkBlue.ToArgb(), IsKnownColour = Color.DarkBlue.IsKnownColor,Colour= Color.DarkBlue.Name}
		};

		var validationResult = await _colourValidator.ValidateAsync(colourPayloadDtos);
		
		return (validationResult, colourPayloadDtos);
	}
}

So the calling code will have returned a ValueTuple with both the ValidationResult and the collection. The other great thing about this type is the named members i.e. ValidationResult and DTOs (hmmm intellisense). Before we get to calling that code, lets pop on over to the query side of our architecture with the query object that will be acted upon by our QueryHandler. The query object is:

public class GetColourQuery : IRequest<Either<List<ColourPayloadDto>, ValidationResult>>
{
	// Nothing to pass to the QueryHandler, so no properties.
}

And that brings us to the custom type Either, which I have obtained from Mikhail Shilkov’s blog (thanks Mikhail!) I’ll just dump the code of Either here and will discuss it further when we examine the code which consumes it:

public class Either<TL, TR>
{
	private readonly TL left;
	private readonly TR right;
	private readonly bool isLeft;

	public Either(TL left)
	{
		this.left = left;
		this.isLeft = true;
	}

	public Either(TR right)
	{
		this.right = right;
		this.isLeft = false;
	}

	public T Match<T>(Func<TL, T> leftFunc, Func<TR, T> rightFunc)
	{
		if (leftFunc == null)
		{
			throw new ArgumentNullException(nameof(leftFunc));
		}

		if (rightFunc == null)
		{
			throw new ArgumentNullException(nameof(rightFunc));
		}

		return this.isLeft ? leftFunc(this.left) : rightFunc(this.right);
	}

	/// <summary>
	/// If right value is assigned, execute an action on it.
	/// </summary>
	/// <param name="rightAction">Action to execute.</param>
	public void DoRight(Action<TR> rightAction)
	{
		if (rightAction == null)
		{
			throw new ArgumentNullException(nameof(rightAction));
		}

		if (!this.isLeft)
		{
			rightAction(this.right);
		}
	}

	public TL LeftOrDefault() => this.Match(l => l, r => default(TL));

	public TR RightOrDefault() => this.Match(l => default(TR), r => r);

	public static implicit operator Either<TL, TR>(TL left) => new Either<TL, TR>(left);

	public static implicit operator Either<TL, TR>(TR right) => new Either<TL, TR>(right);
}

The next piece of code which is relevant is the Query Handler. As per the GetColourQuery, the return type of the Handle method is Either<List<ColourPayloadDto>, ValidationResult> (wrapped in a Task). If you look at the body of that method, depending on whether the ValidationResult is valid, it returns 1 of 2 types of objects i.e. a List or a ValidationResult. So, you can see where the nomenclature for Either came from. How is this done? By the implicit operators of the Either class (otherwise known as the User-defined conversion operators). Because it is implicit, we don’t need to explicitly cast to either List or ValidationResult.

The implicit operators also toggle the all-important isLeft field, which determines what gets returned when the Match method is called (you’ll see where that comes in a bit further on).
public class GetColourQueryHandler : IRequestHandler<GetColourQuery, Either<List<ColourPayloadDto>, ValidationResult>>
{
	private readonly IColoursService _coloursService;

	public GetColourQueryHandler(IColoursService coloursService)
	{
		_coloursService = coloursService;
	}

	public async Task<Either<List<ColourPayloadDto>, ValidationResult>> Handle(GetColourQuery request, CancellationToken cancellationToken)
	{
		var result = await _coloursService.GetColoursAsync();
		
		if (!result.ValidationResult.IsValid)
			return result.ValidationResult;

		return result.DTOs;     
	}
}

This enables us to write code like this (note the invocation of Match):

[HttpGet]
[Route("[action]")]
public async Task<IActionResult> GetColours()
{
	var colours = await _mediator.Send(new GetColourQuery());

	return colours.Match(
		res => OkResponse(colours.LeftOrDefault()),
		res => BadRequest(colours.RightOrDefault())
		);
}

Where validation has passed, the OkResponse will be passed the list of DTOs. Otherwise, the BadRequest will be passed the ValidationResult (which will be a failed validation).

So, again we have achieved an elegant implementation which has enabled us to filter up to the View the validation failure without throwing an exception. Our code will be more performant and our runtime will be all the more happier for it!

Feel free to hit me up in the comments if you have another way of dealing with validation failures that does not involved throwing exceptions.

Validation without Exceptions using a MediatR Pipeline Behavior

First post for 2019 (took me a while to get there).

This is the first post in a 2 post series:

  1. Validation without Exceptions using a MediatR Pipeline Behavior; and
  2. Manual Validation in A Mediatr RequestHandler without Exceptions

In the next 2 posts, I’m going to outline a couple of strategies that I use for returning validation failures in the business layer, without throwing an exception. The posts will also be in the context of Mediatr, which is a very handy library for modelling your HTTP requests (as either queries or commands – think CQRS).

Setting up Mediatr and creating pipelines is beyond the scope of this post. You will see a pipeline behavior being used in the post and can refer to the Mediatr documentation to get up and running quickly, if you are not familiar with Mediatr and how it works (the Github repo also has some good sample code).

The genesis of these posts came from my desire to handle validation failures gracefully and without throwing exceptions. This post will focus on validation in a Mediatr Pipeline behaviour. You may find a lot of code like this on StackOverflow, where an exception is thrown due to a validation failure/s. The exception is caught downstream and everything goes along swimmingly.

But this is not good. Whilst it is easy to implement (that’s a pro), there are a number of cons with this:

  • you should not use Exceptions for control flow. There’s a number of reasons for this, including the high perf cost in throwing exceptions. You don’t do it elsewhere in your code, so why do it for validation failures?
  • a validation failure is not exceptional in nature. It is actually expected. Hence, the validation check. Invoking the exception handling infrastructure should be confined to those things which are not expected.

With that in mind, I needed to find a way to return the validation failures to the client from a Mediatr pipeline, without just throwing (and later catching) an exception. It takes a little bit more effort, but I’m of the view that it is definitely worth it. To the code!

I’ll use an example of a request, where the submitted form:

  • is valid from a “form validation” perspective,
  • but invalid from a “business layer” validation perspective.

Lets say we have a user creation scenario and the user submits a POST request to the server with all valid fields (including the username). However, in this example, there is a business rule which checks to see if the username already exists (in the database). So, whilst the posted form is valid (username is not null), the overall request is ultimately invalid because the user submits a username which already exists in the database.

There’s a lot of moving parts in this, so I’ll start with a validator that is not central to our story. The following validator just validates the POST request. Nothin’ fancy, but it is used here to highlight the point that if the POST has valid inputs, the ModelState will be valid (FluentValidation, handily, bolts on any errors to ASP.NET’s ModelState):

public class CreateUserValidator: AbstractValidator<CreateUserDto>
{
	public CreateUserValidator()
	{
		RuleFor(m => m.Password).NotEmpty();
		RuleFor(m => m.UserName).NotEmpty();
	}
}

Next, I need to create a Command, as we are mutating data by creating a user. This is the command for that:

public class CreateNewUserCommand : IRequest<ValidateableResponse<ApiResponse<int>>>, IValidateable
{
    public CreateUserDto CreateUserDto { get; set; }
}

There’s a couple of key things I need to explain here. The IValidateable interface is just an empty marker interface. This tells my pipeline that this command requires validation. The ValidateableResponse class is the other big one here.

In the normal Mediatr workflow, I would just return the ApiResponse by itself. However, if validation fails, that will not be the object type which is returned. ApiResponse has no information about errors, which we need to convey back to the client. So, we wrap it in a ValidateableResponse, which looks like this:

public class ValidateableResponse
{
	private readonly IList<string> _errorMessages;

	public ValidateableResponse(IList<string> errors = null)
	{
		_errorMessages = errors ?? new List<string>();
	}

	public bool IsValidResponse => !_errorMessages.Any();

	public IReadOnlyCollection<string> Errors => new ReadOnlyCollection<string>(_errorMessages);
}

public class ValidateableResponse<TModel> : ValidateableResponse
	where TModel : class
{

	public ValidateableResponse(TModel model, IList<string> validationErrors = null)
		: base(validationErrors)
	{
		Result = model;
	}

	public TModel Result { get; }
}

And the CommandHandler will look like this:

public class CreateNewUserCommandHandler : IRequestHandler<CreateNewUserCommand, ValidateableResponse<ApiResponse<int>>>
{
	private readonly UserManager<IdpUser> _userManager;

	public CreateNewUserCommandHandler(UserManager<IdpUser> userManager)
	{
		_userManager = userManager;
	}

	public async Task<ValidateableResponse<ApiResponse<int>>> Handle(CreateNewUserCommand request,
		CancellationToken cancellationToken)
	{
		var dto = request.Dto;

		var newAppUser = new IdpUser
		{
			UserName = dto.UserName.Trim(),                
			Password = dto.Password.Trim()
		};

		var result = await _userManager.CreateAsync(newAppUser, dto.Password);

		if (result.Succeeded)
		{
			await _userManager.AddClaimsAsync(
				newAppUser,
				new[] 
				{
					new Claim("access", dto.UserRole),
					new Claim("given_name", dto.UserName)
				}
			);
			
            var apiResponse = new ApiResponse<int>
            {
                Data = newAppUser.Id,
                Outcome = new OperationOutcome
                {
                    Message = string.Empty, OpResult = OpResult.Success
                }
            };			

			return new ValidateableResponse<ApiResponse<int>>(apiResponse);
		}

		return new ValidateableResponse<ApiResponse<int>>(
			null,
			result.Errors
				.Select(e => string.Concat(e.Code, GeneralPurpose.UniqueDelimiter, e.Description))
				.ToList()
			);
	}
}

By doing this, despite the outcome, the same type of object is returned i.e. a ValidateableResponse. If all goes well, we just get the Data property, which in this case, will be an ApiResponse. If validation fails, there will be a populated Errors collection. The outcome is easily checked by querying the IsValidResponse property. This enables us to write code like this:

[HttpPost]
[Route("[action]")]
public async Task<IActionResult> CreateUser([FromBody]CreateUserDto userDto)
{
    var response = await _mediator.Send(new CreateNewUserCommand {CreateUserDto = userDto});

	return result.IsValidResponse
		? CreatedAtRoute(routeValues: new
		{
			controller = "User",
			action = nameof(UserController.GetUser),
			id = result.Result.Data
			version = HttpContext.GetRequestedApiVersion().ToString()
		}, result.Result)
		: BadRequestResponse(Enumerable.Empty<string>(), operationOutcome: new OperationOutcome
		{
			OpResult =OpResult.Fail, 
			IsError = false,
			IsValidationFail = true,
			Errors = result.Errors
		});

}

As you can see, no try/catch block (we will save that for the custom action filters or middleware).

Finally, let’s now look at the pipeline behavior class which draws this all together; the component which validates our command and returns a ValidateableResponse , with a populated Errors list, where validation has failed:

public class BusinessValidationPipeline<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
	where TResponse : class
	where TRequest : IValidateable
{
	private readonly IValidator<TRequest> _compositeValidator;
	private readonly ILogger<TRequest> _logger;
	private readonly ICurrentUser _currentUser;

	public BusinessValidationPipeline(IValidator<TRequest> compositeValidator, ILogger<TRequest> logger, ICurrentUser currentUser)
	{
		_compositeValidator = compositeValidator;
		_logger = logger;
		_currentUser = currentUser;
	}

	public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
	{
		var result = await _compositeValidator.ValidateAsync(request, cancellationToken);

		if (!result.IsValid)
		{
			_logger.LogError(EventIDs.EventIdPipelineThrown,
				MessageTemplates.ValidationErrorsLog,
				result.Errors.Select(s => s.ErrorMessage).Aggregate((acc, curr) => acc += string.Concat("_|_", curr)),
				_currentUser.UserName
				);

			var responseType = typeof(TResponse);

			if (responseType.IsGenericType)
			{
				var resultType = responseType.GetGenericArguments()[0];
				var inValidResponse = typeof(ValidateableResponse<>).MakeGenericType(resultType);

				var invalidResponse =
					Activator.CreateInstance(inValidResponse, null, result.Errors.Select(s => s.ErrorMessage).ToList()) as TResponse;

				return invalidResponse;
			}
		}

		var response = await next();

		return response;
	}
}

If the request fails validation, log it, then generate a ValidateableResponse. This must be done and returned before the next pipeline behavior is invoked (to short-circuit the pipeline). Thus, it is returned before the call to await next() which would be called if everything went well.

Another really cool aspect of this setup is that this pipeline behavior won’t even run unless the TRequest implements IValidateable. Notice how the following generic constraint is placed on the TRequest parameter – where TRequest : IValidateable. To achieve this, you use dependency injection to ensure that this part of the pipeline does not even get injected where the command, which is moving through the pipleline, does not implement IValidateable. So, no need for any if statement in the pipleline behavior class like if(TRequest is IValidateable). An example of such an IOC configuration, using SimpleInjector, would look like this:

Container.RegisterSingleton<IMediator, Mediator>();
Container.Register(typeof(IRequestHandler<,>), assemblies, Lifestyle.Singleton);

Container.Collection.Register(typeof(IPipelineBehavior<,>), new[]
{                
	typeof(LogContextPipeline<,>),
	typeof(BusinessValidationPipeline<,>),
	typeof(TransactionPipelineBehaviour<,>),
	typeof(GenericPipelineBehavior<,>)
});

I’ll also just touch on the reflection which has been used to create the return object where validation fails. Obviously, as this pipeline behavior serves a variety of requests, generics is used to provide that flexibility. That also means we can’t just “new” up an object as we don’t know the closed generic type of TResponse. So, we use reflection to interrogate the response object and from there are able to construct the ValidateableResponse, using the Activator class. Some people will assert that reflection is expensive. It’s not. It really isn’t (unless you are building something where performance is absolutely critical, like a web-server). The perf expense of such a manoeuvre is negligible and pales in comparison to the expense of throwing an exception.

My next post is going to deal with the same notion of validations without exceptions, except the validation will happen in a different place (in the business layer layer itself [i.e. not in a pipeline behavior]) and I will be using a functional programming technique to achieve that end.

Server Name Indication – Bind Different Certificates to 1 IP Address Using the Same Port

In the old days, you could only bind a single SSL certificate to an IP address in IIS. So, if I was using host-headers to have more than 1 site at the same IP address, I could only bind a single SSL certificate to port 443 of one of those WebSites. This was a bummer. In my day job, owing to some limitations, we have our Testing Site on the same server as our Staging Site. As a result, I’d have to bind the Test Site’s certificate to a different port. And as the web server can only have 1 default port for SSL, the 2 urls would be:

  • https://somesite.staging.organisation.org/
  • https://somesite.testing.organisation.org:444/

Nowadays, you can have your cake and eat it. And all it takes is a single checkbox:
Server Name Indication

It’s called Server Name Indication and if the CheckBox is checked for the sites using the same port (presumably 443), then you can bind different certificates to different sites (with distinct host-headers) on the same IP address and the same port.

MembershipReboot Presentation for ADNUG

On Wednesday night I delivered a presentation about MembershipReboot, a claims-aware authentication library for ASP.NET. Here are some links relevant to the content, in addition to the PowerPoint presentation which I used:

Powerpoint presentation:

Lock – the Good, the Bad and the Enhanced

The Good

The lock keyword in C# is very useful for writing thread-safe code. However, it does have its limitations. Before we get to those, I’ll talk you through how to use lock.
The following class FileAccessorNoThreadSafety has a single method called DoOperation. It writes a FileStream to disk, writes text to it and then reads it in again.

public class FileAccessorNoThreadSafety
{
	private static int _count;

	public void DoOperation()
	{
		try
		{
			var fs = new FileStream(Constants.TextFileName, FileMode.Append, FileAccess.Write);

			using (var sw = new StreamWriter(fs))
			{
				sw.Write("writing line with count {0}", _count);
				Console.WriteLine("writing line with count {0}", _count);
				sw.Flush();
			}

			fs = new FileStream(Constants.TextFileName, FileMode.Open, FileAccess.Read);

			using (var sr = new StreamReader(fs))
			{
				_count++;
				Trace.WriteLine(string.Format("{0}", sr.ReadToEnd()));
			}
		}
		catch (IOException ioException)
		{
			Console.WriteLine("{0} - {1}", ioException.GetType().Name, ioException.Message);
			Console.WriteLine("Execution deliberately ended due to {0}", ioException.GetType().Name);
			Console.WriteLine("Exiting");
			Trace.WriteLine(string.Format("Execution deliberately ended due to {0}", ioException.GetType().Name));
			Trace.WriteLine(string.Format("Exiting {0}", Thread.CurrentThread.ManagedThreadId));

			Environment.Exit(0); // kill the whole process
		}
		catch (Exception exception)
		{
			Console.WriteLine("{0} - {1}", exception.GetType().Name, exception.Message);
			Console.WriteLine("Execution deliberately ended due to {0}", exception.GetType().Name);
			Console.WriteLine("Exiting");
			Trace.WriteLine(string.Format("Execution deliberately ended due to {{0}}{0}", exception.GetType().Name));
			Trace.WriteLine(string.Format("Exiting {0}", Thread.CurrentThread.ManagedThreadId));

			Environment.Exit(0); // kill the whole process
		}
	}
}

Note that the FileStream is in append mode, so every time that method is invoked, the line of text is appended to the end of the existing text in the file.

The following method is the Main method of a console application which spins up 1000 threads, all looking to invoke DoOperation at the same time (relatively):

private static void Main()
{
	EnsureTextFile();
	Trace.WriteLine(string.Format("Main thread {0}", Thread.CurrentThread.ManagedThreadId));

	Thread[] threads = new Thread[1000];
	string oi = string.Empty;

	var fileAccessor = new FileAccessorNoThreadSafety();
	//var fileAccessor = new FileAccessorThreadSafe();

	for (int i = 0; i < threads.Length; i++)
	{
		threads[i] = new Thread(fileAccessor.DoOperation);
	}

	for (int i = 0; i < threads.Length; i++)
	{
		threads[i].Start();
	}

	Console.ReadLine();
}

private static void EnsureTextFile()
{
	if (!File.Exists(Constants.TextFileName))
	{
		using (File.CreateText(Constants.TextFileName))
		{
			//  do nothing
			//  "using" disposes of Stream returned by CreateText method
		}
	}
}

As all of those threads are simultaneously trying to access the same resource (the file written by DoOperation), it very quickly throws an IOException. So, we have code which is not thread-safe that results in an exception, if more than one thread attempts to invoke it. How can we fix that?

The easy way, is with the lock keyword, which I have used in a method of the same name in another class called FileAccessorThreadSafe:

public class FileAccessorThreadSafe
{
	private static int _count;
	private readonly object threadLock = new object();

	public void DoOperation()
	{
		try
		{
			lock (threadLock)
			{
				var fs = new FileStream(Constants.TextFileName, FileMode.Append, FileAccess.Write);

				using (var sw = new StreamWriter(fs))
				{
					sw.WriteLine("writing line with count {0}", _count);
					Console.WriteLine("writing line with count {0}", _count);
					sw.Flush();
				}

				fs = new FileStream(Constants.TextFileName, FileMode.Open, FileAccess.Read);

				using (var sr = new StreamReader(fs))
				{
					_count++;
					Trace.WriteLine(sr.ReadToEnd() + " " + _count);
				}
			}
		}
		catch (IOException ioException)
		{
			Console.WriteLine("{0} - {1}", ioException.GetType().Name, ioException.Message);

		}
		catch (Exception exception)
		{

			Console.WriteLine("{0} - {1}", exception.GetType().Name, exception.Message);
		}
	}
}

You’ll find that every thread is able to successfully complete the DoOperation method. In effect, you have a blocking call on each thread until each thread is able to acquire a lock on the resource. In layman’s terms, each thread waits patiently for the resource to be released until it is able to acquire a lock. That being the case, no 2 threads are working with the resource at the same time. Lets take a closer look.

The lock keyword is actually a shortened version of something like this (using the DoOperation method to demonstrate):

bool acquired = false;
object tmp = threadLock;

Monitor.Enter(tmp, ref acquired);

try
{
	var fs = new FileStream(Constants.TextFileName, FileMode.Append, FileAccess.Write);

	using (var sw = new StreamWriter(fs))
	{
		sw.WriteLine("writing line with count {0}", _count);
		Console.WriteLine("writing line with count {0}", _count);
		sw.Flush();
	}

	fs = new FileStream(Constants.TextFileName, FileMode.Open, FileAccess.Read);

	using (var sr = new StreamReader(fs))
	{
		_count++;
		Trace.WriteLine(sr.ReadToEnd() + " " + _count);
	}
}
finally
{
	if (acquired)
	{
		Monitor.Exit(tmp);
	}
}

The Monitor class is what is actually used to lock down the resource for the use of that particular thread and in a finally block, so long as the lock was successfully acquired, the Monitor releases its hold on the resource.
Thus, if you do need finer grain control, you may want to use that longer notation. You may find yourself in situations where you want to clean things up in such a way that having that full code is required.

The Bad

So what is the problem with lock? One word – deadlocks. Whilst I’ve never experienced a deadlock, smarter people than I have stated that they are possible. To demonstrate a deadlock, I have written a class with the 2 methods, LockIntThenFloat and LockFloatThenInt, which are specifically designed to deadlock each other:

public class TypeLocker
{
	public void LockIntThenFloat()
	{
		lock (typeof(int))
		{
			Console.WriteLine("Thread {0} got its first lock", Thread.CurrentThread.ManagedThreadId);


			Thread.Sleep(500);

			Console.WriteLine("Sleep over for thread {0}", Thread.CurrentThread.ManagedThreadId);

			lock (typeof(float))
			{
				Console.WriteLine("Thread {0} got both locks", Thread.CurrentThread.ManagedThreadId);
			}

		}
	}

	public void LockFloatThenInt()
	{
		lock (typeof(float))
		{
			Console.WriteLine("Thread {0} got its first lock", Thread.CurrentThread.ManagedThreadId);

			Thread.Sleep(500);

			Console.WriteLine("Sleep over for thread {0}", Thread.CurrentThread.ManagedThreadId);

			lock (typeof(int))
			{
				Console.WriteLine("Thread {0} got both locks", Thread.CurrentThread.ManagedThreadId);
			}
		}
	}  
}

To see that in action, the following console application will never exit:

static void Main()
{
	Console.WriteLine("Deadlock means that the app will never exit.{0}", Environment.NewLine);

	TypeLocker typeLockerInt = new TypeLocker();
	TypeLocker typeLockerFloat = new TypeLocker();

	Thread floatLockFirst = new Thread(typeLockerFloat.LockFloatThenInt);
	Thread intLockFirst = new Thread(typeLockerInt.LockIntThenFloat);

	floatLockFirst.Start();
	intLockFirst.Start();

	//  This will never ever exit
}

So, now that we know that deadlocks are possible and have actually seen one in action, what does the framework give us to solve the problem that sees the lock keyword come a cropper?

The Enhanced

A couple of really switched on guys tackled this issue and put their work on Github.
We can now modify our code in the following way and avoid deadlocks by using timeouts:

public class TypeLockerWithTimeout
{
	public void LockIntThenFloat()
	{
		lock (typeof (int))
		{
			Console.WriteLine("Thread {0} got its first lock", Thread.CurrentThread.ManagedThreadId);

			Thread.Sleep(500);
		}

		Console.WriteLine("Sleep over for thread {0}", Thread.CurrentThread.ManagedThreadId);

		try
		{
			TimedLock timedLock = TimedLock.Lock(typeof (float), TimeSpan.FromSeconds(2));

			Console.WriteLine("Thread {0} got both locks", Thread.CurrentThread.ManagedThreadId);

			timedLock.Dispose();
		}
		catch (LockTimeoutException e)
		{
			Console.WriteLine("Couldn't get a lock!");
			StackTrace otherStack = e.GetBlockingStackTrace(5000);
			if (otherStack == null)
			{
				Console.WriteLine("Couldn't get other stack!");
			}
			else
			{
				Console.WriteLine("Stack trace of thread that owns lock!");
			}
		}
	}

	public void LockFloatThenInt()
	{
		lock (typeof (float))
		{
			Console.WriteLine("Thread {0} got its first lock", Thread.CurrentThread.ManagedThreadId);

			Thread.Sleep(500);
		}

		Console.WriteLine("Sleep over for thread {0}", Thread.CurrentThread.ManagedThreadId);

		try
		{
			TimedLock timedLock = TimedLock.Lock(typeof (int), TimeSpan.FromSeconds(2));
			Console.WriteLine("Thread {0} got both locks", Thread.CurrentThread.ManagedThreadId);
			timedLock.Dispose();
		}
		catch (LockTimeoutException e)
		{
			Console.WriteLine("Couldn't get a lock!");
			StackTrace otherStack = e.GetBlockingStackTrace(5000);
			if (otherStack == null)
			{
				Console.WriteLine("Couldn't get other stack!");
			}
			else
			{
				Console.WriteLine("Stack trace of thread that owns lock!");
			}
		}
	}
}

In the methods of that modified class, you can see that I am still using lock to get the first lock. When it comes to locking down that next resource, I employ Haack’s TimedLock class which uses a timeout of 2 seconds. That is enough time to wait for the locked resource (which was locked by the other method) to be released.

This exercise gave me a much better understanding of lock. I hope it does for you as well.

The source code for this article can be downloaded here: