How to limit the amount of concurrent async I/O operations?

前端 未结 14 2755
遇见更好的自我
遇见更好的自我 2020-11-22 01:27
// let\'s say there is a list of 1000+ URLs
string[] urls = { \"http://google.com\", \"http://yahoo.com\", ... };

// now let\'s send HTTP requests to each of these          


        
14条回答
  •  一个人的身影
    2020-11-22 01:59

    Theo Yaung example is nice, but there is a variant without list of waiting tasks.

     class SomeChecker
     {
        private const int ThreadCount=20;
        private CountdownEvent _countdownEvent;
        private SemaphoreSlim _throttler;
    
        public Task Check(IList urls)
        {
            _countdownEvent = new CountdownEvent(urls.Count);
            _throttler = new SemaphoreSlim(ThreadCount); 
    
            return Task.Run( // prevent UI thread lock
                async  () =>{
                    foreach (var url in urls)
                    {
                        // do an async wait until we can schedule again
                        await _throttler.WaitAsync();
                        ProccessUrl(url); // NOT await
                    }
                    //instead of await Task.WhenAll(allTasks);
                    _countdownEvent.Wait();
                });
        }
    
        private async Task ProccessUrl(string url)
        {
            try
            {
                var page = await new WebClient()
                           .DownloadStringTaskAsync(new Uri(url)); 
                ProccessResult(page);
            }
            finally
            {
                _throttler.Release();
                _countdownEvent.Signal();
            }
        }
    
        private void ProccessResult(string page){/*....*/}
    }
    

提交回复
热议问题