Stuff - mainly geek, a little diabetes, some rant. Possibly all three in the same post. Basically anything I find interesting and/or worth sharing.
These are my personal views, unless I've been hacked.
The C# using statement (as opposed to the using directive) is usually described along the lines of syntactic sugar for a try/finally block that guarantees to call the Dispose method of a class or struct that implements IDisposable. This is correct except for a subtle detail that I'll explain in a while.
Consider the following code:
using System;
public class Program
{
public static void Main(string[] args)
{
using (var myDisposable = new MyDisposable())
{
myDisposable.DoThing();
}
// not allowed, myDisposable is out of scope
//myDisposable.DoThing();
}
}
public class MyDisposable : IDisposable
{
public void DoThing()
{
// method intentionally left blank
}
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
Assuming the standard description of the using statement, this is how lines 7-12 above are expanded by the compiler:
var myDisposable = new MyDisposable();
try
{
myDisposable.DoThing();
}
finally
{
if (myDisposable != null)
{
((IDisposable)myDisposable).Dispose();
}
}
// not allowed, myDisposable is out of scope
//myDisposable.DoThing();
However, the comment at line 13 is no longer correct; the variable myDisposable is now available in the whole method following its declaration.
Variable Scope
Assuming a variable is declared within the using statement, the compiler will scope that variable, by adding a set of braces around its usage. Here's the full method as it is compiled - note the braces at lines 3 and 16:
public static void Main(string[] args)
{
{
var myDisposable = new MyDisposable();
try
{
myDisposable.DoThing();
}
finally
{
if (myDisposable != null)
{
((IDisposable)myDisposable).Dispose();
}
}
}
// not allowed, myDisposable is out of scope
//myDisposable.DoThing();
}
Of course, it is possible to live more dangerously by applying the using statement on a variable declared outside scope of the using statement:
public static void Main(string[] args)
{
var myDisposable = new MyDisposable();
using (myDisposable)
{
myDisposable.DoThing();
}
// careful, myDisposable has been disposed
myDisposable.DoThing();
}
This is the second in what might soon be a series of blogposts on C# syntactic sugar - that is, where the language allows you to express your intent using a keyword, and the compiler restructures the code to perform how you expect it to.
The params Keyword
This post is about the params keyword. This keyword allows you to define an array parameter to a method, which can be specified by its caller as a list of values. Here's an example that demonstrates the flexible nature of the parameter:
public static void Main(string[] args)
{
// All valid calls
DoStuff();
DoStuff(1);
DoStuff(1, 2);
DoStuff(new[] { 1, 2 });
}
private static void DoStuff(params int[] ints)
{
// this method intentionally left blank
}
The IL
So, what does the compiler does with this? Here's the IL that the compiler produces for the DoStuff method, with the interesting bit highlighted:
Inspired by a talk I saw a DevWeek 2013 by Andrew Clymer, I took a look at the IL created by the C# compiler when the lock keyword is used. If you don't need an introduction to how the lock statement works, scroll down a bit and skip the first couple of C# snippets.
The Lock Statement
As a brief introduction to the lock keyword, it is used as a mechanism to allow access by a thread to a critical piece of code. Typically, this is when you have the possibility of multiple threads trampling on each other's data.
Take the sample code here:
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
public static void Main(string[] args)
{
// Create a totaliser
var totaliser = new Totaliser();
// Set it off on a new thread
Task.Run(() => totaliser.ModifyTotal());
// Give the totaliser a chance to do something
Thread.Sleep(100);
// Write the current total
Console.WriteLine(string.Format("Current value of Total: {0}", totaliser.Total));
Console.ReadLine();
}
}
public class Totaliser
{
public int Total { get; private set; }
// increment the total to 500, then down again to 0
public void ModifyTotal()
{
for (var counter = 0; counter < 5000000; ++counter)
{
Total++;
}
for (var counter = 0; counter < 5000000; ++counter)
{
Total--;
}
}
}
The intent of the Totaliser class is to be able to freely increment and decrement its Total without any external visibility of what's happening. Unfortunately, because its Total property is publicly readable, the Total can be read at any stage in the increment-decrement cycle in a multi-threaded environment:
A solution to this problem is to use the lock statement, around the reads and writes to Total:
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
public static void Main(string[] args)
{
// Create a totaliser
var totaliser = new Totaliser();
// Set it off on a new thread
Task.Run(() => totaliser.ModifyTotal());
// Give the totaliser a chance to do something
Thread.Sleep(100);
// Write the current total
Console.WriteLine(string.Format("Current value of Total: {0}", totaliser.Total));
Console.ReadLine();
}
}
public class Totaliser
{
private object lockObject = new object();
private int _total;
public int Total
{
get
{
lock (lockObject)
{
return _total;
}
}
private set { _total = value; }
}
// increment the total to 500, then down again to 0
public void ModifyTotal()
{
lock (lockObject)
{
for (var counter = 0; counter < 5000000; ++counter)
{
Total++;
}
for (var counter = 0; counter < 5000000; ++counter)
{
Total--;
}
}
}
}
See the new lockObject at line 26, and the lock statement at lines 33 and 44.
The lock statement forces the thread to obtain a lock on the lockObject before it can proceed; if another thread has the lock, it must wait until it's been released. The result is a success:
The IL
Looking at the IL produced by the compiler, you can see the framework objects used to implement the lock:
The System.Threading.Monitor class has a couple of options when trying to grab a lock on an object, in particular the TryEnter method. This has an overload that takes a timeout value in milliseconds, which specifies how long this thread should wait to obtain the lock
I don't advocate rewriting your lock statements to use the longhand versions above, but this hopefully removes a layer of abstraction between you and your multi-threaded executable.
If you have a Dictionary<T,T> and you want to upsert a value (i.e. update or insert depending on its existence), you don't have to perform the existence check yourself:
It turns out the dictionary's set indexer will do the check for you. All you need is
This applies to the .Net Dictionary<T,T>, SortedDictionary<T,T> and SortedList<T,T> implementations of IDictionary<T,T> . But bear in mind that if you're coding to the abstraction IDictionary<T,T>, you can't guarantee that the specific implementation you're using will work this way.
Our team has started running Ship It Days (a short write-up here) as a way of driving innovation for the company. The basic idea is that the whole development team gets 2 days to work on small projects, each of which will either deliver a feature for the company or increase the technical knowledge within the team.
As an example, over 2 days this week, we [a team of 2 developers and 2 testers] produced a heatmap of phone calls in progress on our network, across the world. We produced code to surface phone call data, map the source and destination phone number prefixes to geographic points, and overlay the routes on Google Maps' world map. The map is likely to be displayed in the Network Operations Centre as a dashboard item to see how busy the network is, and by customers to see what calls are in progress on their contact centre.
Although the 2 days were an absolute success in terms of delivering the feature (it won 2 company-wide votes, Best Minimum Viable Product and Most Innovative), for me the work involved was too close to my day job for me to get *really* excited. Don't get me wrong; I love the job I do and could think of few jobs I'd rather do than write code all day. But. This project was about surfacing, transforming and visualising data, using WebAPI, C# and JavaScript.
Disclaimer: this demo is not intended to show best practice in C#, javascript, HTML, MVC, Visual Studio, NuGet etc etc. It is intended to use as a picture-book style guide to creating RPC communications between a web client and an ASP.Net application using SignalR.
Note: the code is not as simple as I'd hoped, but it changed to use a singleton to hold the timer, after the lack of best practice with a SignalR hub was pointed out by one of its authors.