Skip to main content
1 of 3

Is this a sensible way to throttle duplicate requests in a httpmodule

I'm writing a method to throttle duplicate requests taking place within multiple HttpModule instances within a web application.

Currently I have the following setup:

// Container for semaphores
private static readonly ConcurrentDictionary<string, SemaphoreSlim> 
SemaphoreSlims = new ConcurrentDictionary<string, SemaphoreSlim>();

// Wrapper for getting semaphore
private static SemaphoreSlim GetSemaphoreSlim(string id)
{
    return SemaphoreSlims.GetOrAdd(id, new SemaphoreSlim(1, 1));
}


private async Task ProcessImageAsync(HttpContext context)
{
    // `hash` is the request path hashed.
    SemaphoreSlim semaphore = GetSemaphoreSlim(hash);
    await semaphore.WaitAsync();

    try
    {

    // Do awaitable task

    }
    finally
    {
        semaphore.Release();
    }
}

This will work but I have no way of disposing of the semaphore instances since I need to preserve the ConcurrentDictionary and cannot dispose of a semaphore within the Dispose() method for that HttpModule instance as it could be currently waiting in another instance.

By my calculation it would take up ~156 megabytes of memory for 1 million items stored in the dictionary. It's not a massive amount but I'd really like it to be scalable and somehow find a way to clean up after myself.

Is this a sensible pattern and is there a way I can improve on it?