Вы должны использовать Microsoft Reactive Framework (он же Rx) - NuGet System.Reactive
и добавить using System.Reactive.Linq;
- тогда вы можете сделать это:
var query =
from x in Observable.Range(0, 1000)
from y in Observable.Range(0, 1000)
from r in Observable.Start(() => GetResult(x, y))
select new { x, y, r };
IDisposable subscription =
query
.Buffer(100)
.Subscribe(results =>
{
/* do something with each buffered list of results */
});
Теперь это не совсем то же самое, что ваш текущий код, но он дает вам блоки с 100 результатами, как только они становятся доступными, используя максимальную емкость пула потоков.
Вы можете изменить его, чтобы установить параллелизм следующим образом:
var query =
from x in Observable.Range(0, 1000)
from y in Observable.Range(0, 1000)
select Observable.Start(() => new { x, y, r = GetResult(x, y) });
IDisposable subscription =
query
.Merge(maxConcurrent: 100) // limit to 100 threads
.Buffer(count: 100) // produce 100 results at a time
.Subscribe(results =>
{
/* do something with the list of results */
});
Если вы хотите остановить код до его естественного завершения, просто наберите subscription.Dispose();
.
Rx имеет тенденцию производить намного более чистый код, ИМХО.