我有一个调用web api的控制台应用程序并获取服务列表。然后它循环并调用每个服务。
我有以下内容:
static int Main(string[] args)
{
...
Task.WaitAll(Process());
}
private static async Task BeginProcess()
{
using(HttpClientHandler handler = new HttpClientHandler())
{
handler.UseDefaultCredentials = true;
using(var client = new HttpClient(handler))
{
var response = client.GetStringAsync(_baseUrl);
List<Service> services = new List<Service>();
services = jss.Deserialize<List<Service>>(response.Result);
client.Timeout = new TimeSpan(0,3,0);
foreach(var service in services)
{
Console.WriteLine("Running " + service.Name);
var _serviceResponse = await client.PostAsync(_baseURL + service.Id.ToString(), null);
Console.WriteLine(service.Name + " responded with " + _serviceRepsonse.StatusCode);
}
}
}
}
不幸的是,此代码按顺序处理每个服务,而不是并行调用。问题是,我不确定如何使这些调用并行运行。
答案 0 :(得分:3)
虽然我接受了答案,但我终于登上了这个我觉得更简洁的。
await Task.WhenAll(services.Select(async s => {
Console.WriteLine("Running " + s.Name);
var _serviceResponse = await client.PostAsync(...);
Console.WriteLine(s.Name + " responded with " + _serviceResponse.StatusCode);
}));
答案 1 :(得分:2)
答案可以在C#cookbook中的Concurrency中找到:
static async Task<string> DownloadAllAsync(IEnumerable<string> urls){
var httpClient = new HttpClient();
var downloads = urls.select(url => httpClient.getStringAsync(url));
Task<string>[] tasks = downloads.ToArray(); //-> tasks are started
//now that you have an array of tasks you can wait for them all to finish
string[] htmlPages = await Task.WhenAll(tasks);
return string.Concat(htmlPages);
}
这里的关键点是:
答案 2 :(得分:1)
正如@SLaks所提到的,你需要用这些行代替你的循环...
var asyncTasks = new Dictionary<Service, Task>();
foreach(var service in services)
{
Console.WriteLine("Running " + service.Name);
asyncTasks.Add(service, client.PostAsync(_baseURL + service.Id.ToString(), null));
}
// All tasks are running, so wait for all of them to finish here
await Task.WhenAll(asyncTasks);
foreach(var service in asyncTasks.Keys) {
Console.WriteLine("Service " + service.Name + " returned " + syncTasks[service].Result);
}
希望它有所帮助。
答案 3 :(得分:0)
改变这个:
foreach(var service in services)
{
Console.WriteLine("Running " + service.Name);
var _serviceResponse = await client.PostAsync(_baseURL + service.Id.ToString(), null);
Console.WriteLine(service.Name + " responded with " + _serviceRepsonse.StatusCode);
}
到此:
var serviceCallTaskList = new List<Task<HttpResponseMessage>>();
foreach(var service in services)
{
Console.WriteLine("Running " + service.Name);
serviceCallTaskList.Add(client.PostAsync(_baseURL + service.Id.ToString(), null));
}
HttpResponseMessage[] responseArray = await Task.WhenAll(serviceCallTaskList);
for(int i = 0; i < responseArray.Length; i++)
{
Console.WriteLine(services[i].Name + " responded with " + responseArray[i].StatusCode);
}