Throttle actions by number per period
private readonly TimeSpan _maxPeriod;
private readonly System.Threading.SemaphoreSlim _throttleActions, _throttlePeriods;



I would add using System.Threading; at the top of the code file, so as to avoid having to fully qualify everything you're referencing in that namespace.

Also, at a glance (especially with the fully qualified SemaphoreSlim) it looks like you're declaring two readonly fields here, but there's really 3. I find this requires less brain juice to glance at:

private readonly TimeSpan _maxPeriod;
private readonly SemaphoreSlim _throttleActions;
private readonly SemaphoreSlim _throttlePeriods;


That said I like that the fields are readonly and that you're using an underscore prefix, which avoids having to qualify the fields with this in the constructor:

public Throttle(int maxActions, TimeSpan maxPeriod)
{
    this.throttleActions = new SemaphoreSlim(maxActions, maxActions);
    this.throttlePeriods = new SemaphoreSlim(maxActions, maxActions);
    this.maxPeriod = maxPeriod;
}


...and the reason you would have to qualify the fields in the constructor without that underscore prefix, is because you have a consistent naming scheme for your constructor parameters vs. the fields they're assigning, and that's excellent.

I'm not very familiar with asynchronous programming, multithreading or even the TPL - but Throttle tickles my Name-O-Meter™, as it's a verb more than a noun.. and class names should be nouns. Would Throttler be weird for a class like this? The only time a verb seems fine to me is when the class is static, such as Convert.


public Task&lt;T&gt; Queue&lt;T&gt;(Func&lt;T&gt; action, System.Threading.CancellationToken cancel)



Here we have the opposite situation: you're using a noun where a verb would be more appropriate - Enqueue&lt;T&gt; sounds more like it.

I'm on the fence about these comments:


    // Release after period
    // - Allow bursts up to maxActions requests at once
    // - Do not allow more than maxActions requests per period



It seems to me that they wouldn't be needed if the constructor had XML comments for its parameters:

/// &lt;summary&gt;
/// Instantiates a new &lt;c&gt;Throttle&lt;/c&gt; object
/// &lt;/summary&gt;
/// &lt;param name="maxActions"&gt;The maximum number of actions allowed per period.&lt;/param&gt;
/// &lt;param name="maxPeriod"&gt;The time span to use for delaying tasks.&lt;/param&gt;
public Throttle(int maxActions, TimeSpan maxPeriod)
{
    this.throttleActions = new SemaphoreSlim(maxActions, maxActions);
    this.throttlePeriods = new SemaphoreSlim(maxActions, maxActions);
    this.maxPeriod = maxPeriod;
}


I've never used Task.Delay, so I'm not 100% on the actual meaning of maxPeriod - but you get the idea: not only XML documentation cleans up comments in the middle of your implementation, it's also picked up by IntelliSense and shown when you're writing the client code.