Просто сделайте results
поточно-ориентированной коллекцией производителя-потребителя, такой как BlockingCollection . У него есть GetConsumingEnumerable
метод, который возвращает IEnumerable, который выдаст элемент, как только другая часть кода добавит его в коллекцию.
var results = new BlockingCollection<Result>();
async Task ProducerAsync()
{
await Task.Run(() => // I removed the async here as it was not needed
{
Parallel.For(0, k, i =>
{
var tt = Sites.oneNews(cat, sites[i]);
results.Add(tt.Result);
});
});
results.CompleteAdding(); // notify any enumerable that no more items will arrive
}
void Consumer()
{
foreach (var result in results.GetConsumingEnumerable())
{
// each result will arrive here as soon as it becomes available
}
}
Или если вы хотите использовать результаты в том же методе, где они производятся (обратите внимание, что я переместил вызов на CompleteAdding
внутри Task.Run
):
var results = new BlockingCollection<Result>();
var producerTask = Task.Run(() => // I removed the async here as it was not needed
{
Parallel.For(0, k, i =>
{
var tt = Sites.oneNews(cat, sites[i]);
results.Add(tt.Result);
});
results.CompleteAdding(); // notify any enumerable that no more items will arrive
});
foreach (var result in results.GetConsumingEnumerable())
{
// each result will arrive here as soon as it becomes available
}
await producerTask;