Вот 2 примера:
List<Func<Reference>> referenceDelegates = new List<Func<Reference>>();
foreach (string url in urls)
{
// not async as I need to add this to a list without invoking it.
// making it async would require a return type of Task<Reference> and
// force the task to execute when adding it to a list
// e.g. referenceDelegates.Add(GetReference());
Reference GetReference()
{
// uses the url string and gets data from a bunch of different servers
// from around the world, a different server with each foreach iteration
// returns Result;
}
referenceDelegates.Add(GetReference);
}
List<Task<Reference>> referenceTasks = referenceDelegates
.AsParallel()
.Select(d => Task.Run(d.Invoke))
.ToList();
List<Reference> references = Task.WhenAll(referenceTasks)
.Result
.ToList();
// work with results
или же
List<Func<Task<Reference>>> referenceDelegates = new List<Func<Task<Reference>>>();
foreach (string url in urls)
{
async Task<Reference> GetReference()
{
// uses the url string and gets data from a bunch of different servers
// from around the world, a different server with each foreach iteration
// returns Result;
}
referenceDelegates.Add(GetReference);
}
List<Task<Reference>> referenceTasks = referenceDelegates
.AsParallel()
.Select(d => Task.Run(d.Invoke))
.ToList();
Task.WhenAll(referenceTasks);
List<Reference> result = referenceTasks
.Select(l => l.Result)
.ToList();
// work with results
Что это за самый эффективный (самый быстрый с наименьшим объемом памяти) способ одновременно вызвать список делегатов и дождаться результата?
Может, его можно переписать?
1 ответ
Я предлагаю вам просто попробовать и посмотреть, но, что более важно, я сомневаюсь, что это важно.
Поскольку это задачи, которые запрашивают результаты с других серверов в Интернете, время, необходимое для их добавления в список и их вызова, будет неизмеримо мало по сравнению с тем, сколько времени на самом деле требуется для выполнения каждого из них. Только по этой причине они все должны быть Task<Reference> в любом случае, и их вызов не будет блокироваться, поэтому вы можете добавить их все в задачу, а затем подождать.
То, что вы хотите, вероятно, будет примерно таким:
List<Task<Reference>> referenceTasks = new List<Task<Reference>>();
foreach (string url in urls)
{
async Task<Reference> GetReference()
{
// uses the url string and gets data from a bunch of different servers
// from around the world, a different server with each foreach iteration
// returns Result;
}
referenceTasks.Add(GetReference());
}
await Task.WhenAll(referenceTasks);
List<Reference> results = new List<Reference>();
foreach(var r in referenceTasks)
{
results.Add(await r);
}
// work with results
![Самый быстрый / самый эффективный способ параллельного вызова списка делегатов в .NET Core 5 [closed] TheFAQ.ru](https://thefaq.ru/wp-content/uploads/2023/01/logo-250.png)
Почему вы определяете одну и ту же локальную функцию (n раз) внутри цикла foreach?
— Питер Чала
Это так, как было написано в вопросе, вы можете предположить, что это какое-то закрытие над
url.— Турксарама