C#同时运行许多异步任务

问题描述:

我对于异步任务有点陌生。C#同时运行许多异步任务

我有一个功能,可以从特定的大学网站上获取学生证和数据,并提供所需的ID。

private static HttpClient client = new HttpClient(); 
    public static async Task<Student> ParseAsync(string departmentLink, int id, CancellationToken ct) 
    { 
     string website = string.Format(departmentLink, id); 
     try 
     { 
      string data; 
      var stream = await client.GetAsync(website, ct); 
      using (var reader = new StreamReader(await stream.Content.ReadAsStreamAsync(), Encoding.GetEncoding("windows-1256"))) 
       data = reader.ReadToEnd(); 

      //Parse data here and return Student. 
     } catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
    } 

它正常工作。虽然有时我需要为很多学生运行这个功能,所以我用下面的

 for(int i = ids.first; i <= ids.last; i++) 
     { 
      tasks[i - ids.first] = ParseStudentData.ParseAsync(entity.Link, i, cts.Token).ContinueWith(t => 
      { 
       Dispatcher.Invoke(() => 
       { 
        listview_students.Items.Add(t.Result); 
        //Students.Add(t.Result); 
        //lbl_count.Content = $"{listview_students.Items.Count}/{testerino.Length}"; 
       }); 
      }); 
     } 

我存储在数组任务后等待他们。

只要学生人数介于(0,〜600?)之间,这也可以很好地工作,这是随机的。 然后对于仍然没有被解析过的所有其他学生抛出任务被取消

请记住,我从不使用取消标记。

我需要在如此多的学生上运行这个函数,它可以完全达到〜9000个异步任务。那么发生了什么?

当您在如此短的时间内排队处理9000个请求时,您基本上会在网站上创建拒绝服务攻击。这不仅会导致你的错误,但它可能会使网站失效。最好将并发请求的数量限制在一个更合理的值(比如说30)。虽然有可能是几种方法可以做到这一点,我想到的是:

private async Task Test() 
{ 
    var tasks = new List<Task>(); 
    for (int i = ids.first; i <= ids.last; i++) 
    { 
    tasks.Add(/* Do stuff */); 
    await WaitList(tasks, 30); 
    } 
} 

private async Task WaitList(IList<Task> tasks, int maxSize) 
{ 
    while (tasks.Count > maxSize) 
    { 
    var completed = await Task.WhenAny(tasks).ConfigureAwait(false); 
    tasks.Remove(completed); 
    } 
} 

其他方法可能利用使用.NET类生产者/消费者模式,如BlockingCollection