C# 如何向HttpClient.GetAsync返回的任务添加更多详细信息
下面的代码正在异步地从多个url检索内容,并且只要有一个内容通过Task.whenay下载完毕,它就会被处理。但在处理部分,我需要标识符对象。我认为向您展示代码更为清晰:C# 如何向HttpClient.GetAsync返回的任务添加更多详细信息,c#,.net,asynchronous,task-parallel-library,C#,.net,Asynchronous,Task Parallel Library,下面的代码正在异步地从多个url检索内容,并且只要有一个内容通过Task.whenay下载完毕,它就会被处理。但在处理部分,我需要标识符对象。我认为向您展示代码更为清晰: var downloadTasks = new List<Task<string>>(); foreach (var identifier in input.Identifiers) { string url = BuildUrl(identi
var downloadTasks = new List<Task<string>>();
foreach (var identifier in input.Identifiers)
{
string url = BuildUrl(identifier, input.PeriodInYear, input.Interval);
var data = _webRequest.GetData(url, token);
downloadTasks.Add(data); // Here I only add the data, but not the Identifier. I thought about using a List<Tuple<Identifier, Task<string>>, but then I can't use it with Task.WhenAny(...)
}
while (downloadTasks.Count > 0)
{
var finishedDownloadTask = await Task.WhenAny(downloadTasks);
downloadTasks.Remove(finishedDownloadTask);
foreach (var content in await finishedDownloadTask)
{
// hereI I also need the Identifier object here !
}
}
var downloadTasks=newlist();
foreach(input.Identifiers中的var标识符)
{
字符串url=BuildUrl(标识符,input.PeriodInYear,input.Interval);
var data=_webRequest.GetData(url,令牌);
downloadTasks.Add(data);//这里我只添加数据,而不添加标识符。我考虑过使用列表我不认为“构建任务列表”和“等待任务”。任何时候,“从列表中删除已完成任务”的方法都是非常干净的
当我退一步,看看代码,写一个新的异步方法来进行“初始”处理和“后处理”时,我发现我的代码通常更干净。在你的例子中,它看起来像这样:
async Task GetDataAndPostProcessAsync(Identifier identifier, CancellationToken token)
{
var url = BuildUrl(identifier, input.PeriodInYear, input.Interval);
var content = await _webRequest.GetDataAsync(url, token);
// Use 'content' with 'identifier'
}
...
var tasks = input.Identifiers.Select(identifier =>
GetDataAndPostProcessAsync(identifier, token)).ToList();
await Task.WhenAll(tasks);
我在《C#Cookbook》中并发的配方2.6中更详细地介绍了这一点
async Task GetDataAndPostProcessAsync(Identifier identifier, CancellationToken token)
{
var url = BuildUrl(identifier, input.PeriodInYear, input.Interval);
var content = await _webRequest.GetDataAsync(url, token);
// Use 'content' with 'identifier'
}
...
var tasks = input.Identifiers.Select(identifier =>
GetDataAndPostProcessAsync(identifier, token)).ToList();
await Task.WhenAll(tasks);