© 2026 Hedgehog Software, LLC

TwitterGitHubDiscord
More
CommunitiesDocsAboutTermsPrivacy
Search
Star
Setup for Free
C#C
C#•2y ago•
7 replies
stigzler

✅ Using IProgress with await Task.WhenAll(tasks);

I am trying to introduce a IProgress object into the code below. Can't for the life of me figure how to do it. I need the code this way (rather than via a foreach loop) because I am querying an API which limits the number of concurrent threads.
The IProgress objects main ProgressEventArgs will be how many items have been processed and also the url used in each task instance. Thus I need some way to keep track of how many taks have been completed. Any steers? The code:

    
public class Scraper
{
    
    private SemaphoreSlim semaphoreSlim = 7;
    public void Scraper(int concurrentThreads)
    {
        semaphoreSlim = new SemaphoreSlim(concurrentThreads);
        ServicePointManager.FindServicePoint(new Uri(baseUrl)).ConnectionLimit = concurrentThreads;
    }

    public async Task<List<ApiGetStringOutcome>> GetStringsFromUrlList(List<string> apiUrls)
    {
        List<Task<ApiGetStringOutcome>> tasks = new List<Task<ApiGetStringOutcome>>();

        foreach (string apiUrl in apiUrls)
        {
            tasks.Add(GetStringDataAsync(apiUrl));
        }

        await Task.WhenAll(tasks);

        return new List<ApiGetStringOutcome>(tasks.Select(t => t.Result));
    }

    private async Task<ApiGetStringOutcome> GetStringDataAsync(string apiUrl, ApiGameSearchParameters gameSearchParameters = null)
    {
        await semaphoreSlim.WaitAsync(); // Wait until semaphore is available

        try
        {
            HttpResponseMessage response = await httpClient.GetAsync(apiUrl);
        }
        catch (Exception ex)
        {
            // Stuff here
        }
        finally
        {
            semaphoreSlim.Release();
        }
    }
}

public class MainApp
{
    public void Start()
    {        
        // blah...
        getStringOutcomes = await Task.Run(() => apiDataService.GetStringsFromUrlList(urlList));
    }
    
}
    
public class Scraper
{
    
    private SemaphoreSlim semaphoreSlim = 7;
    public void Scraper(int concurrentThreads)
    {
        semaphoreSlim = new SemaphoreSlim(concurrentThreads);
        ServicePointManager.FindServicePoint(new Uri(baseUrl)).ConnectionLimit = concurrentThreads;
    }

    public async Task<List<ApiGetStringOutcome>> GetStringsFromUrlList(List<string> apiUrls)
    {
        List<Task<ApiGetStringOutcome>> tasks = new List<Task<ApiGetStringOutcome>>();

        foreach (string apiUrl in apiUrls)
        {
            tasks.Add(GetStringDataAsync(apiUrl));
        }

        await Task.WhenAll(tasks);

        return new List<ApiGetStringOutcome>(tasks.Select(t => t.Result));
    }

    private async Task<ApiGetStringOutcome> GetStringDataAsync(string apiUrl, ApiGameSearchParameters gameSearchParameters = null)
    {
        await semaphoreSlim.WaitAsync(); // Wait until semaphore is available

        try
        {
            HttpResponseMessage response = await httpClient.GetAsync(apiUrl);
        }
        catch (Exception ex)
        {
            // Stuff here
        }
        finally
        {
            semaphoreSlim.Release();
        }
    }
}

public class MainApp
{
    public void Start()
    {        
        // blah...
        getStringOutcomes = await Task.Run(() => apiDataService.GetStringsFromUrlList(urlList));
    }
    
}
C# banner
C#Join
We are a programming server aimed at coders discussing everything related to C# (CSharp) and .NET.
61,871Members
Resources
Was this page helpful?

Similar Threads

Recent Announcements

Similar Threads

get value from parallel for loop using Task.WhenAll
C#CC# / help
4y ago
❔ Task.WhenAll does not work without Task.Run inside
C#CC# / help
4y ago
❔ Any way to optimize this? Task.WhenAll
C#CC# / help
3y ago