Run async method 8 times in parallel

前端 未结 4 1160
再見小時候
再見小時候 2020-12-01 16:59

How do I turn the following into a Parallel.ForEach?

public async void getThreadContents(String[] threads)
{
    HttpClient client = new HttpClient();
    Li         


        
4条回答
  •  [愿得一人]
    2020-12-01 17:29

    Stephen Toub has a good blog post on implementing a ForEachAsync. Svick's answer is quite good for platforms on which Dataflow is available.

    Here's an alternative, using the partitioner from the TPL:

    public static Task ForEachAsync(this IEnumerable source,
        int degreeOfParallelism, Func body)
    {
      var partitions = Partitioner.Create(source).GetPartitions(degreeOfParallelism);
      var tasks = partitions.Select(async partition =>
      {
        using (partition) 
          while (partition.MoveNext()) 
            await body(partition.Current); 
      });
      return Task.WhenAll(tasks);
    }
    

    You can then use this as such:

    public async Task getThreadContentsAsync(String[] threads)
    {
      HttpClient client = new HttpClient();
      ConcurrentDictionary usernames = new ConcurrentDictionary();
    
      await threads.ForEachAsync(8, async url =>
      {
        HttpResponseMessage response = await client.GetAsync(url);
        String content = await response.Content.ReadAsStringAsync();
        String user;
        foreach (Match match in regex.Matches(content))
        {
          user = match.Groups[1].ToString();
          usernames.TryAdd(user, null);
        }
        progressBar1.PerformStep();
      });
    }
    

提交回复
热议问题