What is the best way to cal API calls in parallel in .net Core, C#?
我想并行调用我的API次数,以便可以快速完成处理。
我下面有三种方法必须并行调用API。 我试图了解哪种是执行此操作的最佳方法。
基本代码
1 2 3 4 5 6 7 8 9 10 11 |
使用Parallel.ForEach的第一种方法
1 2 3 4 5 6 7 8 9 10 | Parallel.ForEach(list,new ParallelOptions() { MaxDegreeOfParallelism = 3 }, index => { var response = client.GetAsync("posts/" + index).Result; var contents = response.Content.ReadAsStringAsync().Result; listResults.Add(contents); Console.WriteLine(contents); }); Console.WriteLine("After all parallel tasks are done with Parallel for each"); |
带有任务的第二种方法。 我不确定这是否并行。 让我知道是否可以
1 2 3 4 5 6 7 8 9 10 11 12 13 | var loadPosts = new List<Task<string>>(); foreach(var post in list) { var response = await client.GetAsync("posts/" + post); var contents = response.Content.ReadAsStringAsync(); loadPosts.Add(contents); Console.WriteLine(contents.Result); } await Task.WhenAll(loadPosts); Console.WriteLine("After all parallel tasks are done with Task When All"); |
使用动作阻止的第三种方法-这是我应该一直做的事情,但我希望听到社区的意见
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | var responses = new List<string>(); var block = new ActionBlock<int>( async x => { var response = await client.GetAsync("posts/" + x); var contents = await response.Content.ReadAsStringAsync(); Console.WriteLine(contents); responses.Add(contents); }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 6, // Parallelize on all cores }); for (int i = 1; i < 5; i++) { block.Post(i); } block.Complete(); await block.Completion; Console.WriteLine("After all parallel tasks are done with Action block"); |
方法2接近。 这是一条经验法则:I / O绑定操作=>使用Tasks / WhenAll(异步),计算绑定操作=>使用并行性。 Http请求是网络I / O。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | foreach (var post in list) { async Task<string> func() { var response = await client.GetAsync("posts/" + post); return await response.Content.ReadAsStringAsync(); } tasks.Add(func()); } await Task.WhenAll(tasks); var postResponses = new List<string>(); foreach (var t in tasks) { var postResponse = await t; //t.Result would be okay too. postResponses.Add(postResponse); Console.WriteLine(postResponse); } |
我将使用以下内容,它无法控制并发性(与您的第3种方法不同,它会并行调度所有HTTP请求),但要简单得多-它只有一个
1 2 3 4 5 6 7 8 |