Я надеюсь, что кто-то может помочь мне найти более эффективное решение моей проблемы ниже. Я использую шаблон возврата IEnumerable yield в многопоточном конвейере. В большинстве случаев это работает отлично, однако у меня есть несколько сценариев, в которых мне нужно, чтобы операции в конвейере выполнялись синхронно, а не в параллельных потоках, чтобы получить правильный результат. (т. е. столкнулись с проблемами параллелизма).
Существующий код:
public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
{
foreach (Row row in rows)
{
//do some work....
yield return row;
}
}
Я думаю о создании необязательного параметра, который контролирует блокировку и неблокировку вывода перечислителя; что-то вроде:
public override IEnumerable<Row> Execute(IEnumerable<Row> rows, bool BlockingExecution)
{
if (BlockingExecution)
{
return BlockingExecute(rows);
}
else
{
return NonBlockingExecute(rows);
}
}
private IEnumerable<Row> NonBlockingExecute(IEnumerable<Row> rows)
{
foreach (Row row in rows)
{
//do some work....
yield return row;
}
}
private IEnumerable<Row> BlockingExecute(IEnumerable<Row> rows)
{
List<Row> BlockingResult = new List<Row>();
foreach(Row r in NonBlockingExecute(rows))
{
BlockingResult.Add(r);
}
return BlockingResult;
}
В функции BlockingExecute кажется неэффективным создавать копию IEnumerable в списке, чтобы принудительно очистить весь конвейер. Есть лучший способ это сделать?
rows
(предположительно возвращая результаты лениво - здесь это называется неблокирующим), либо вы хотите перечислить материализованное перечисляемое, например,rows.ToList()
. Следовательно, вы должны иметь возможность использовать то, что уже доступно в среде .Net. - person Vikas Gupta   schedule 11.11.2014yield return
, не является потокобезопасным, рассмотрите возможность правильной блокировки или что-то вроде разбиение с помощью Parallel.ForEach - person Alexei Levenkov   schedule 11.11.2014