2017-04-03 2 views
2

Je souhaite exécuter un ensemble de requêtes Web, mais définissez un seuil sur le nombre pouvant être démarré simultanément.Throttle WebRequests

je suis tombé sur cette LimitedConcurrencyTaskScheduler example et a essayé de l'utiliser comme si

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

...

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

Cependant, je remarque que même avec un maximum de 1 concurrency, mes tâches semblaient être compléter dans une commande non-FIFO. Lorsque j'ai mis des points d'arrêt dans LimitedConcurrencyLevelTaskScheduler, il est devenu évident qu'il n'est pas utilisé du tout. Je suppose que la façon dont j'utilise TaskFactory.FromAsync ne fait pas ce que j'avais prévu.

Existe-t-il un moyen approprié de limiter les demandes Web simultanées?

Répondre

2

Quand je mets en LimitedConcurrencyLevelTaskScheduler points d'arrêt, il est devenu évident que ce n'est pas utilisé du tout

C'est exact. FromAsync n'utilise pas du tout TaskFactory. En fait, je ne comprends pas vraiment pourquoi cette méthode n'est pas statique.

Vous avez plusieurs façons d'implémenter la limitation. Vous pouvez utiliser le ActionBlock à partir de Microsoft.Tpl.Dataflow. Ou vous pouvez faire votre propre en utilisant 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(); 
    } 
} 
+0

Merci, ce fut une telle goutte de solution! – Chris