当我运行下面的代码时,在"Press Enter to continue... "
调用返回结果之前,会显示消息HttpClient.GetAsync()
。实际的事件顺序:GetAsync()
来电," Press Enter...
"消息出现,然后结果是逐个输出到控制台窗口。在显示" GetAsync()
"" Press Enter...
"之前,我如何等待所有class Program
{
static HttpClient client = new HttpClient();
static void Main(string[] args)
{
RunAsync().Wait();
Console.WriteLine("\n\n\n\nPress Enter to continue... ");
Console.ReadLine();
}
static async Task RunAsync()
{
List<string> urls = new List<string>()
{
"http://www.domain1.com",
"http://www.domain2.com",
"http://www.domain3.com",
"http://www.domain4.com"
};
foreach (var url in urls)
{
DownloadPageAsync(url);
}
}
static async Task<string> DownloadPageAsync(string url)
{
Console.WriteLine("Starting: " + url);
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
// do stuff here
}
Console.WriteLine("Done: " + url);
return response.Content.ToString();
}
}
来电完成消息?
{{1}}
答案 0 :(得分:3)
由于DownloadPageAsync
返回任务,您可以列出所有任务并等待所有任务:
Task.WhenAll(urls.Select(url => DownloadPageAsync(url)))
或简化:
Task.WhenAll(urls.Select(DownloadPageAsync))
答案 1 :(得分:1)
@ patrik-hofman答案很好(已投票)但是,请参阅我的评论
如果您希望顺序发生请求...
将await
添加到DownloadPageAsync
行。
您在async
中使用了RunAsync
,但没有await
。因此,虽然它返回一个任务,但它不等待DownloadPageAsync
调用完成。这意味着该方法只返回一个立即完成的“空”任务。所以你的.Wait()
正在等待什么。
答案 2 :(得分:0)
我认为问题在于您没有等待DownloadPageAsync
方法中的RunAsync()
方法。如果您将RunAsync()
方法更新为以下代码,那么我相信它会按预期运行:
static async Task RunAsync()
{
List<string> urls = new List<string>()
{
"http://www.domain1.com",
"http://www.domain2.com",
"http://www.domain3.com",
"http://www.domain4.com"
};
foreach (var url in urls)
{
// added await here
await DownloadPageAsync(url);
}
}
答案 3 :(得分:-2)
您需要为每个所需的呼叫创建不同的任务,在您的示例中,您正在运行代码而不是等待呼叫。当你调用WhenAll时,它只是为所有人创建一个任务。假设您使用下面的代码,并在每个MakeYouCall方法中插入一个项目列表。该列表将是您需要锁定的共享资源。当创建WhenAll时,如果您不等待结果(调用Wait()),则可以部分填充集合。
spring-data mongo
然后
var register1 = new Action(() => MakeYourCall1());
var register2 = new Action(() => MakeYourCall2());
var register3 = new Action(() => MakeYourCall3());
之后,您可以调用将返回任务的WhenAll,然后等待它。
var t1 = Task.Factory.StartNew(register1);
var t2 = Task.Factory.StartNew(register2);
var t3 = Task.Factory.StartNew(register3);