Дроссельные веб-запросы

Я хочу выполнить кучу WebRequests, но установить порог, сколько можно запускать одновременно.

Я наткнулся на этот LimitedConcurrencyTaskScheduler пример и попытался использовать его так

scheduler = new LimitedConcurrencyLevelTaskScheduler(1);
taskFactory = new TaskFactory(scheduler);

...

    private Task<WebResponse> GetThrottledWebResponse(WebRequest request)
    {
        return taskFactory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
    }

Однако я заметил, что даже при максимальном параллелизме, равном 1, мои задачи, казалось, выполнялись в порядке, отличном от FIFO. Когда я поставил точки останова в LimitedConcurrencyLevelTaskScheduler, стало очевидно, что он вообще не используется. Я предполагаю, что то, как я использую TaskFactory.FromAsync, не делает того, что я ожидал.

Есть ли правильный способ ограничить одновременные веб-запросы?


person Chris    schedule 03.04.2017    source источник


Ответы (1)


Когда я поставил точки останова в LimitedConcurrencyLevelTaskScheduler, стало очевидно, что он вообще не используется

Это правильно. FromAsync вообще не использует TaskFactory. На самом деле, я не очень понимаю, почему этот метод не является статическим.

У вас есть несколько способов реализовать регулирование. Вы можете использовать ActionBlock From Microsoft.Tpl.Dataflow. Или вы можете сделать свой собственный, используя SemaphoreSlim:

private static readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);

private static async Task<WebResponse> GetThrottledWebResponse(WebRequest request)
{
    await Semaphore.WaitAsync().ConfigureAwait(false);

    try
    {
        return await request.GetResponseAsync().ConfigureAwait(false);
    }
    finally
    {
        Semaphore.Release();
    }
}
person Kevin Gosse    schedule 03.04.2017
comment
Спасибо, это было такое простое решение! - person Chris; 04.04.2017