using (new Throttle()) {
... do my expensive operation here ...
}using System;
using System.Collections;
using System.Web;
using System.Web.Caching;
/// <summary>
/// This is used to throttle anything really, it throws an exception if too many are running simultaneously
/// It works by storing the runs in the http cache
/// Use this with a 'using' statement surrounding your work, eg:
///
/// using (new Throttle()) {
/// ... work to be throttled ...
/// }
/// </summary>
public class Throttle : IDisposable
{
// Used to lock all instances of the throttle, so they don't walk over each other when using the http cache
static object cacheLock = new object();
// Max simultaneous users
const int max = 10;
// The timeout in seconds at which to consider each run to have finished anyway, eg in case the throttle forgets to clear it
const int timeout = 30;
// What prefix to give the names in the cache
const string cacheEntryNamePrefix = "Throttle";
// The name of the cache entry used by this particular throttled run
string thisCacheEntryName;
/// <summary>
/// Checks that we haven't hit the throttle, and if so it throws an exception
/// Then it registers the current run in the cache, to be forgotten when finished
/// </summary>
public Throttle() {
lock (cacheLock) {
// Check we haven't hit the maximum
int runners = 0;
foreach (DictionaryEntry kv in HttpContext.Current.Cache)
if (kv.Key.ToString().StartsWith(cacheEntryNamePrefix))
runners++;
if (runners >= max)
throw new Exception("Too many people accessing the system right now. Please retry soon.");
// Register this one into the cache
thisCacheEntryName = cacheEntryNamePrefix + System.Guid.NewGuid().ToString();
HttpContext.Current.Cache.Add(thisCacheEntryName, 1, null, DateTime.Now.AddSeconds(timeout), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
}
}
/// <summary>
/// Removes the entry from the cache
/// </summary>
public void Dispose() {
lock (cacheLock) {
HttpContext.Current.Cache.Remove(thisCacheEntryName);
}
}
}Thanks for reading! And if you want to get in touch, I'd love to hear from you: chris.hulbert at gmail.

(Comp Sci, Hons - UTS)
Software Developer (Freelancer / Contractor) in Australia.
I have worked at places such as Google, Cochlear, Assembly Payments, News Corp, Fox Sports, NineMSN, FetchTV, Coles, Woolworths, Trust Bank, and Westpac, among others. If you're looking for help developing an iOS app, drop me a line!
Get in touch:
[email protected]
github.com/chrishulbert
linkedin